2013-01-23 99 views
3

我在我的.net安裝程序應用程序中面臨一個問題,它將一起安裝三個Windows應用程序。在這三個應用程序中,一個是Windows服務。所以,我的安裝程序項目有三個來自這三個Windows應用程序的主要輸出。.net安裝程序,自定義操作,停止和卸載Windows服務

安裝後,所有這些將按預期方式安裝,Windows Service將在安裝後自動「啓動」。但是,如果我卸載應用程序(而Windows服務處於「RUNNING」模式),安裝程序將顯示一個「正在使用的文件」對話框,並且最終會導致服務未被卸載,而其他事情將被刪除。但是,如果Windows Service在卸載之前停止,它將很好地完成。

我假設發生上述問題是因爲安裝程序應用程序將嘗試刪除service.exe文件(因爲它也捆綁到安裝程序中)。

我想下面的交替:

  1. 我試圖通過增加中,我試圖阻止該服務自定義安裝程序來克服這一點。但是,這似乎也沒有奏效。原因是,在「卸載」自定義操作之前將執行默認的「卸載」操作。 (失敗)

  2. 將Windows服務應用程序的「主要輸出」的「永久」屬性設置爲「true」。我假設安裝程序將簡單地跳過與主要輸出相關的文件。但(失敗)

任何人都面臨過這樣的問題,請分享你的想法。

如何在卸載前停止服務以便卸載成功完成?

回答

0

我很久以前就和windows服務有類似的問題,並能通過調用WaitForStatus(ServiceControllerStatus)方法解決它。該服務需要一段時間才能關閉,並且在服務完全停止之前繼續進行。編寫卸載邏輯以及當Shutdown狀態已停止時您想要執行的操作。

如果您正在卸載並且想要在卸載前停止服務,那麼您需要重寫卸載自定義操作,添加代碼以停止它,然後致電base.Uninstall。 請記住,具有15秒限制的WaitForStatus可能沒有足夠的時間讓服務關閉,具體取決於它在響應中的響應程度以及它在關機中的功能。另外請確保您撥打 ServiceController(或如本例所示關閉),因爲如果您不這樣做,那麼內部服務句柄將不會立即釋放,並且如果它仍在使用中,則服務無法卸載。

MSDN link

這是如何實現這一點的,並記錄在事件記錄器只例如:

public override void Uninstall(System.Collections.IDictionary savedState) 
{ 
ServiceController controller = new ServiceController("My Service"); 
try 
{ 
    if (controller.Status == ServiceControllerStatus.Running | controller.Status == ServiceControllerStatus.Paused) 
    { 
    controller.Stop(); 
    controller.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 0, 30)); 
    controller.Close(); 
    } 
} 
catch (Exception ex) 
{ 
    string source = "My Service Installer"; 
    string log = "Application"; 
    if (!EventLog.SourceExists(source)) 
    { 
    EventLog.CreateEventSource(source, log); 
    } 
    EventLog eLog = new EventLog(); 
    eLog.Source = source; 
    eLog.WriteEntry(string.Concat(@"The service could not be stopped. Please stop the service manually. Error: ", ex.Message), EventLogEntryType.Error); 
} 
finally 
{ 
    base.Uninstall(savedState); 
} 
} 
+0

感謝焉。 我已經有東西了,請看下面的代碼: ServiceController controller = new ServiceController(this。_mtlTestServiceName); 嘗試 { 如果(controller.Status == ServiceControllerStatus.Running | controller.Status == ServiceControllerStatus.Paused) { controller.Stop(); controller.WaitForStatus(ServiceControllerStatus.Stopped,new TimeSpan(0,0,0,15)); controller.Close(); } } 但到目前爲止沒有用:( – user2003520

相關問題