上次的文章介紹了 TopShelf 這個框架,能夠幫助我們使用很簡單的方式建構出一個 Windows Service,這次我們要使用 .NET Core 內建的功能,並搭配 Service Control (sc.exe) 來幫我們把 Application 註冊到 Windows Service 當中
環境
- Windows 10
- Rider 2018.2.3
- .NET Core 2.1
步驟
我們要使用的是 .NET Core MVC (Model-View-Controller) 的專案,大家對 .NET MVC 專案的印象都停留在他必須要佈署到 IIS 上面才可以運行,但其實 .NET Core 本身可以透過 Microsoft.AspNetCore.Hosting.WindowsServices
讓 Windows Service 來 Host 整個服務。
建立專案
將平台改為 win7-x64
(因為要執行在 Windows 上)
1 | <Project Sdk="Microsoft.NET.Sdk.Web"> |
安裝套件
安裝 Microsoft.AspNetCore.Hosting.WindowsServices
套件,讓服務可以裝載到 Windows Service 中
微調程式碼
1 | public static void Main(string[] args) |
發行 .NET Core 應用程式
1 | dotnet publish --configuration Release |
我們可以在 bin/Release/netcoreapp2.1/win7-x64
當中找到剛剛 publish 指令產生的檔案
使用 sc.exe
為了要把這個服務註冊到 Windows Service 中,我們需要藉助 sc.exe (Service Control) 來幫忙,首先要找到我們 publish 的安裝檔位置,並且使用以下指令來建立 Windows Service
1 | sc create MySvc binPath= "E:\Temp\deploy\NetCoreWinSvcLab.exe" |
注意 binPath=
和 "E:\Temp\deploy\NetCoreWinSvcLab.exe"
之間一定要有空格
啟動 Service
1 | sc start MySvc |
查詢 Service 狀態
1 | sc query MySvc |
可以看到有沒有在執行
同樣的也可以透過 Windows 提供的 Windows 服務管理員介面來看服務是不是有執行起來
因為我們這次註冊的服務是一個 Web Application,所以也可以透過網頁來看服務是不是有執行
1 | http://localhost:5000/ |
停止 Service
1 | sc stop MySvc |
解除安裝 Service
注意在解除安裝之前要先讓服務處於 STOPPED
狀態
1 | sc delete MySvc |
處理事件 (啟動、停止)
文章看到現在其實會發現把 Application 註冊到 Windows Service 本身不是特別的麻煩,但會發現他沒有像是 TopShelf 包裝好的那些類似生命週期的事件,不過我們可以透過繼承 WebHostService
類別來覆寫 OnStarting
, OnStarted
, OnStopping
, OnStopped
原本的行為
1 | public static class CustomWebHostServiceExtension |
然後修改一下 Program.cs,改成使用剛剛定義好的 RunAsCustomService
1 | public static void Main(string[] args) |
再來依照前面的 command line 語法啟動/停止 service
並觀察是否有出現 log.txt 在我們預期的路徑,以及 log 內容是不是真的依照這個生命週期觸發
1 | //> sc start MySvc |
結論
當初使用 TopShelf 的時候覺得很方便,但是畢竟還是依附在寫好的框架底下,不過必須說,TopSHelf 畢竟還是已經推出了一段時間的框架,功能上其實算是完整,可以透過程式或是命令列參數來調整設定,但 .NET Core MVC + sc.exe
這個組合,有很多設定可能要自己處理,相對來說比較沒有這麼方便。
不過單純就整個開專案到安裝 Service 的步驟,整體操作起來我認為沒有到非常複雜,各位讀者可以照著本文或是下面參考資料的文章做一次,將自己的 Application 裝載到 Windows 服務當中來執行。
參考資料
- https://docs.microsoft.com/zh-tw/aspnet/core/host-and-deploy/windows-service?view=aspnetcore-2.1
- https://dzone.com/articles/running-aspnet-core-application-as-windows-service