2010-03-24 35 views
3

我是新編寫Windows Service應用程序並遇到問題。什麼是Application.ProcessMessages,Application.Handle和Application.Terminated在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)終止。

我的問題是..是否有可以在服務應用程序中使用的等效過程,還是應該在服務應用程序中以不同的方式解決問題?

任何幫助,將不勝感激

回答

4

不要使用的ShellExecute()啓動一個.exe文件。這對服務是非常重要的,這些服務並不在殼牌內部開始。使用CreateProcess()(在Vista和更高版本上,改爲使用CreateProcesAsUser())。

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

5

請注意,從Vista和7中的服務運行應用程序可能無法按預期工作。 Vista和7中的服務在不同的窗口站中運行,這對登錄用戶不可見。

另請注意,如果應用程序由服務執行,它將以服務用戶權限運行 - 應使用CreateProcessAsUser()運行,以避免以非常高的權限運行應用程序(即LocalSystem,除非是原因),因爲它可能會給系統帶來巨大的安全風險。

如果您需要檢查應用程序是否退出,則不需要像這樣循環等待。在單獨的線程上使用WaitForSingleObject()。它不會吞噬所有這些CPU週期,Windows本身將以禮貌的方式表示退出。

服務主線程應該簡單地監聽服務控制管理器命令。 Delphi允許在使用主線程進行實際處理時使用ProcessRequests()來處理這些調用,但最好遵循文檔並使用單獨的線程進行處理。

+0

+1,所有*非常*好點。 – mghie 2010-03-28 07:31:00

相關問題