我是编写Windows服务应用程序并遇到问题的新手.
用Delphi编写,我编写了一个普通的Windows应用程序来检查和调试代码的主要部分,现在必须将它转换为NT服务.
我的代码必须启动一个Windows应用程序,我使用以下代码.
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;
Run Code Online (Sandbox Code Playgroud)
当这被放入服务应用程序时,编译器失败并出现3个错误:未声明的标识符.1)处理2)ProcessMessages和3)终止.
我的问题是..是否有可以在服务应用程序中使用的等效过程,或者我应该在服务应用程序中以不同方式处理问题?
任何帮助,将不胜感激
不要使用 ShellExecute() 启动 .exe 文件。这对于服务来说尤其重要,因为服务本来就不在 Shell 内运行。为此,请使用 CreateProcess()(在 Vista 及更高版本上,请改用 CreateProcesAsUser())。
使用 ServiceThread.ProcessRequests() 和 ServiceThread.Termminate 而不是 Application.ProcessMessages() 和 Application.Termulated。
小智 5
请注意,从Vista和7中的服务运行应用程序可能无法按预期工作.Vista和7中的服务在不同的Windows工作站中运行,登录用户看不到.
还要注意,如果应用程序由服务执行,它将以服务用户权限运行 - 它应该使用CreateProcessAsUser()运行,以避免运行具有非常高级权限的应用程序(即LocalSystem,除非这是原因),因为它可能会使系统面临巨大的安全风险.
如果您需要检查应用程序是否退出,则无需像这样循环.在单独的线程上使用WaitForSingleObject().它不会吞没所有这些CPU周期,Windows本身将以礼貌的方式发出退出信号.
服务主线程应该只是监听服务控制管理器命令.当使用主线程进行实际处理时,Delphi允许使用ProcessRequests()来处理这些调用,但最好遵循文档并使用单独的线程进行处理.