2013-02-27 112 views
2

我已經構建了一個Windows服務來監視我們的服務器上的一些設置,我已經開發了不少WinForm和WPF應用程序,但對於Windows服務我是一個絕對的新手,這就是爲什麼我訴諸於msdn,並按照教程how to create a simple service。現在,我可以安裝該服務,並使其運行,但只有當我從微軟教程中刪減了一些零碎......但我很好奇爲什麼,當我按照教程,我的服務在啓動時得到一個意外的錯誤。Windows服務 - 在啓動時崩潰

經過一些測試,似乎該服務似乎OnStart方法崩潰在SetServiceStatus()

public partial class MyService: ServiceBase 
{ 
    private static ManualResetEvent pause = new ManualResetEvent(false); 

    [DllImport("ADVAPI32.DLL", EntryPoint = "SetServiceStatus")] 
    public static extern bool SetServiceStatus(IntPtr hServiceStatus, SERVICE_STATUS lpServiceStatus); 
    private SERVICE_STATUS myServiceStatus; 

    private Thread workerThread = null; 
    public MyService() 
    { 
     InitializeComponent(); 
     CanPauseAndContinue = true; 
     CanHandleSessionChangeEvent = true; 
     ServiceName = "MyService"; 
    } 
    static void Main() 
    { 
     // Load the service into memory. 
     System.ServiceProcess.ServiceBase.Run(MyService()); 
    } 

    protected override void OnStart(string[] args) 
    { 
     IntPtr handle = this.ServiceHandle; 
     myServiceStatus.currentState = (int)State.SERVICE_START_PENDING; 
     **SetServiceStatus(handle, myServiceStatus);** 
     // Start a separate thread that does the actual work. 
     if ((workerThread == null) || ((workerThread.ThreadState & (System.Threading.ThreadState.Unstarted | System.Threading.ThreadState.Stopped)) != 0)) 
     { 
      workerThread = new Thread(new ThreadStart(ServiceWorkerMethod)); 
      workerThread.Start(); 
     } 
     myServiceStatus.currentState = (int)State.SERVICE_RUNNING; 
     SetServiceStatus(handle, myServiceStatus); 
    } 
} 

現在我的服務似乎運行得很好,當我註釋掉SetServiceStatus()線。爲什麼這會失敗?這是一個權利問題還是我完全忽略了這一點?

+2

你有調用'SetServiceStatus'的一些具體原因嗎?這不是嚴格要求,你可能只是擺脫這些電話。 – CodingGorilla 2013-02-27 17:55:34

+1

你可以按照這個簡單的教程來做一個簡單的Windows服務。所有這些外部電話都不需要您的服務工作。 [http://www.codeproject.com/Articles/14353/Creating-a-Basic-Windows-Service-in-C] – 2013-02-27 19:12:15

+0

那麼我沒有具體的原因,只是試圖跟隨msdn,並想知道爲什麼在地球上它失敗了。 – XikiryoX 2013-02-27 22:05:30

回答

4

通常,在使用框架實施託管服務時,您不必調用SetServiceStatus。也就是說,如果你確實叫它,你需要在使用它之前完全初始化SERVICE_STATUS。您目前只設置了狀態,但none of the other variables

這是在SetServiceStatus的最佳實踐中建議的:「初始化SERVICE_STATUS結構中的所有字段,確保存在有效的檢查點並等待未決狀態的提示值,並使用合理的等待提示。

+1

的確,他所說的。實施(和響應)事件,例如OnStart(),OnStop()和其他各種電源事件將根據您對這些事件的處理隱式管理您的服務的狀態。你不應該需要任何extern /直接訪問Win32 API來完成你在這裏說明的內容。 – 2013-02-27 18:01:52

+0

所以一般來說,創建一個像這樣的託管服務時,我不需要使用SetServiceStatus。如果我這樣做...還有一些我需要擔心的事情。謝謝,你們在這裏的黑暗中散發出一些光芒。乾杯。 – XikiryoX 2013-02-27 22:09:56