在Windows服务应用程序中,Application.ProcessMessages,Application.Handle和Application.Terminated的等价物是什么?

Dav*_*idB 3 delphi delphi-7

我是编写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)终止.

我的问题是..是否有可以在服务应用程序中使用的等效过程,或者我应该在服务应用程序中以不同方式处理问题?

任何帮助,将不胜感激

Rem*_*eau 5

不要使用 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()来处理这些调用,但最好遵循文档并使用单独的线程进行处理.