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

时间:2010-03-24 14:12:50

标签: 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;

当它被放入服务应用程序时,编译器失败并出现3个错误:未声明的标识符.. 1)处理 2)ProcessMessages和 3)终止。

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

任何帮助将不胜感激

2 个答案:

答案 0 :(得分:5)

请注意,从Vista和7中的服务运行应用程序可能无法按预期工作。 Vista和7中的服务在不同的Windows工作站中运行,登录用户看不到。

还要注意,如果应用程序由服务执行,它将以服务用户权限运行 - 它应该使用CreateProcessAsUser()运行,以避免运行具有非常高级权限的应用程序(即LocalSystem,除非是因为它可以使系统面临巨大的安全风险。

如果您需要检查应用程序是否退出,则无需像这样循环等待。在单独的线程上使用WaitForSingleObject()。它不会吞没所有这些CPU周期,Windows本身会以礼貌的方式发出退出信号。

服务主线程应该只监听Service Control Manager命令。当使用主线程进行实际处理时,Delphi允许使用ProcessRequests()来处理这些调用,但最好遵循文档并使用单独的线程进行处理。

答案 1 :(得分:4)

不要使用ShellExecute()来启动.exe文件。这在服务中尤其重要,这些服务不会在Shell中运行。使用CreateProcess()(在Vista及更高版本中,改为使用CreateProcesAsUser())。

使用ServiceThread.ProcessRequests()和ServiceThread.Terminated而不是Application.ProcessMessages()和Application.Terminated。