What is the equivalent of Application.ProcessMessages, Application.Handle and Application.Terminated in a Windows Service application?
I am new to Writing Windows Service apps and having problems.
Written in Delphi, I have written a normal windows application to check and debug the major parts of the code and now have to convert it to an NT Service.
My code has to launch a windows application which I do using the following code.
function Run_Program : boolean;
var SEInfo : TShellExecuteInfo;
ExitCode : DWORD;
begin
Result := false;
FillChar(SEInfo, SizeOf(SEInfo),0);
SEInfo.cbSize :=SizeOf(TShellExecuteInfo);
With SEInfo do
begin
fMask := SEE_MASK_NOCLOSEPROCESS;
Wnd := **Application.Handle**;
lpFile := PChar(Exe_Prog);
lpParameters := PChar(Exe_Param);
nShow := SW_SHOWNORMAL;
end;
If ShellExecuteEx(@SEInfo) then
begin
repeat
Application.ProcessMessages;
GetExitCodeProcess(SEInfo.hProcess, ExitCode);
until (ExitCode <> STILL_ACTIVE) OR Application.Terminated OR NOT q1.fieldbyName('Delay').AsBoolean;
If ExitCode <> STILL_ACTIVE then Record_Event(Exe_Prog + ' completed ') else
Record_Event(Exe_Prog + ' activated ');
Result := true;
end
else Record_Event('Error Starting '+ Exe_Prog+ ' ');
end;
When th开发者_StackOverflow中文版is is put in the service app the compiler fails with 3 errors: Undeclared identifiers.. 1) Handle 2) ProcessMessages and 3) Terminated.
My question is.. are there equivalent procedures that can be used in a service application or should I approach the problem differently in a service application?
Any help would be appreciated
Don't use ShellExecute() to launch a .exe file. This is especially important in services, which do not run within the Shell to begin with. Use CreateProcess() for that (on Vista and later, use CreateProcesAsUser() instead).
Use ServiceThread.ProcessRequests() and ServiceThread.Terminated instead of Application.ProcessMessages() and Application.Terminated.
Be aware that running applications from a service in Vista and 7 may not work as expected. Services in Vista and 7 are run in a different windows station which is not visible to the logged on user.
Also be aware that if an application is executed by a service, it runs with the service user privilege - it should be run using CreateProcessAsUser() to avoid to run an application with very elevated privileges (i.e. LocalSystem, unless that is the reason), because it can expose the system to big security risks.
If you need to check if an application exits there is no need to wait in a loop like that. Use WaitForSingleObject() on a separate thread. It won't swallow all those CPU cycles, Windows itself will signal the exit in a polite manner.
The service main thread should simply listen for Service Control Manager commands. Delphi allows to use ProcessRequests() to process those calls when using the main thread for actual processing, but it is better to follow the documentation and use a separate thread for processing.
精彩评论