﻿# 如何讓 Windows Service 應用程式在特定條件下自行停止

之前分享過 "[如何透過 C# 啟動、停止、重新啟動 Windows 服務](/post/2009/04/08/Windows-Service-Start-Stop-Restart-in-CSharp)"，這是從一個「程序外」的角度來談如何透過 C# 控制服務狀態。但是最近卻遇到需要在**執行中的 Windows Service 應用程式**中在特定運作條件下需**自行停止**的情況，也就是「程序本身」要「自我了結」的狀況，我真的試了好久才試出來。

廢話不多說，答案只有一個，而且還很簡單，就是直接用 [ServiceController](http://msdn.microsoft.com/zh-tw/library/system.serviceprocess.servicecontroller.aspx) 類別就可以將自己結束了。

```
new ServiceController(this.ServiceName).Stop();
```

因為每一個服務都有 this.ServiceName 屬性紀錄服務名稱，正好可以直接傳入給 [ServiceController](http://msdn.microsoft.com/zh-tw/library/system.serviceprocess.servicecontroller.aspx) 並直接執行 [Stop()](http://msdn.microsoft.com/zh-tw/library/system.serviceprocess.servicecontroller.stop.aspx) 方法即可。

看起來好簡單對吧！我試了3 個小時  =.=''

* * *

以下是嘗試的歷史過程，都是錯誤示範，請不要學：

1\. 先嘗試直接呼叫 this.OnStop() 與 this.Stop() 甚至於呼叫 base.Stop() 或 base.OnStop() 停止服務

    雖然直接這樣呼叫可以中斷所有執行中的執行緒(Thread)，但是在 **服務管理員**(Service Control Manager；SCM) 中還是會顯示 "**已啟動**" 的狀態，不夠漂亮。

2\. 透過引發例外事件(Exception)將服務停止

    這會在事件檢視器(EventLog)中出現一條紅紅的錯誤訊息，堪稱最殘暴的服務停止法 (小朋友不要學)。

3\. 利用 [Thread.Abort()](http://msdn.microsoft.com/zh-tw/library/ty8d3wta.aspx) 方法中斷程式執行

    除了跟第一點一樣會在**事件檢視器**中出現一條紅紅的錯誤訊息，也挺[邪惡](http://haacked.com/archive/2004/11/12/how-to-stop-a-thread.aspx)的。\[[參考](<Plumbing the Depths of the ThreadAbortException Using Rotor>)\]

4\. 利用 [Environment.Exit(0)](http://msdn.microsoft.com/zh-tw/library/system.environment.exit.aspx) 結束程式執行 ( 也是跟第 1 點差不多殘暴 )

    雖然感覺上優雅的以 ExitCode = 0 結束，但對 **服務管理員**(Service Control Manager；SCM) 來說，還是一樣算是「非預期的結束」，在**事件檢視器**中還是會出現一條紅紅的錯誤訊息，所以這樣的停止法還是不夠**優雅(elegant)**。

5\. 利用 [Application.Exit()](http://msdn.microsoft.com/zh-tw/library/ms157894.aspx) 結束程式執行

    這是有招試到沒招才會用這個方法亂槍打鳥，不要再亂了～

* * *

說實在的，我之所以會花三個小時才解決此問題，其中有大半時間在網上衝浪找資料，結果找到一大堆**廢資訊**，而且在 MSDN 上也沒有相關的說明或範例 (也許老外都覺得太簡單了)，最後再嘗試了多種方案後才決定呼叫自己的**老爸**([ServiceController](http://msdn.microsoft.com/zh-tw/library/system.serviceprocess.servicecontroller.aspx))把自己停止看看，結果最後才試成功，有點 ......

**相關連結**

-   [Windows 服務應用程式簡介](http://msdn.microsoft.com/zh-tw/library/d56de412.aspx) ( [Introduction to Windows Service Applications](http://msdn.microsoft.com/en-us/library/d56de412\(VS.80\).aspx) )
-   [Mastering Windows Services](http://www.codeproject.com/KB/dotnet/WindowsServices.aspx)
-   [ServiceBase 類別](http://msdn.microsoft.com/zh-tw/library/system.serviceprocess.servicebase\(VS.80\).aspx)
