I have a windows service created with Delphi 7, with StartType = stSystem.
Now I need to launch an application to make some things for me.
This application has a MainForm and other GDI resources.
The parameter passed to the application assigns values for some controls (like edits and memos) and then click at a button….
I’m trying this:
var
token: cardinal;
si: TStartupInfo;
pi: TProcessInformation;
begin
if not LogonUser('admintest', '', 'secret123', LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, token) then
RaiseLastOSError;
try
if not ImpersonateLoggedOnUser(token) then
RaiseLastOSError;
fillchar(si, sizeof(si), 0);
si.cb := sizeof(si);
si.lpDesktop := PChar('winsta0\default');
if not CreateProcessAsUser(token, nil, '"c:\...\myapp.exe" -doCrazyThings', nil, nil, false, NORMAL_PRIORITY_CLASS or CREATE_NEW_CONSOLE, nil, nil, si, pi) then
RaiseLastOSError;
CloseHandle(pi.hThread);
waitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
finally
CLoseHandle(token);
end;
end;
When I run my service executable as a normal application (-noservice), it starts as a Forms.Application and creates a MainForm with a button “Start”.
*The button runs the same code that service run, but it doesn’t works and it’s rasing the eror code 1314 at createprocessasuser.*
Why? What is the diference between SYSTEM service and a normal application launched by a administrator?
My environment is a Windows 7 Pro x64
What am I doing wrong?
How can I solve this?
Can someone post an example?
Error 1314 is
ERROR_PRIVILEGE_NOT_HELD, which means your calling thread is missing a required privilege to runCreateProcessAsUser(). You don’t need to, nor should you be, impersonating the user token in order to launch a new process in the user’s desktop. You should be letting the thread use the service’s credentials, not the user’s credentials, when callingCreateProcessAsUser(). It will make sure the new process is run inside the user’s account and desktop for you, so get rid of the call toImpersonateLoggedOnUser()and see ifCreateProcessAsUser()starts working.Update: read the documentation: