以 .NET Core 快速開發 Windows Services 或 Linux systemd 服務
透過 .NET Core 3.0,提供的便利套件,我們可以快速的開發出 Windows Services 或 Linux systemd,擴展 .NET Core 的應用領域。
背景資訊
現在的 .NET Core 版本為 v3.0.0-preview8。
專案的執行環境
- SDK 3.0.100-preview8-013656
- VSCode 1.37
- Windows 10
- CentOS 7
到這裡安裝 .NET Core SDK 3.0。
(透過安裝 preview 版 的 Visual Studio 也可以建立 .NET Core 3 的服務專案)
Windows Services 範例
利用 dotnet cli 建立服務專案
.NET Core 3.0 提供了 worker
範本,用來建立系統服務的基本專案。
在新增的專案目錄中,執行1
dotnet new worker
輸出如下:1
2
3
4
5
6
7The template "Worker Service" was created successfully.
Processing post-creation actions...
Running 'dotnet restore' on D:\Temp\netcore\netcorewinsrv\netcorewinsrv.csproj...
D:\Temp\netcore\netcorewinsrv\netcorewinsrv.csproj 的還原於 260.69 ms 完成。
Restore succeeded.
安裝 WindowsServices 套件
此時此刻,最新版本為 3.0.0-preview8.19405.41
dotnet add package Microsoft.Extensions.Hosting.WindowsServices --version 3.0.0-preview8.19405.4
啟用 WindowsService 功能
增加 UseWindowsService() 到 Program.cs 的 HostBuilder 中,以啟用 WindowsService 功能。1
2
3
4
5
6
7public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
});
實做功能
修改 Worker.cs 實做要提供的功能。
範例中,每秒輸出時間到 /var/log/netcoreservice.log 這個檔案中。1
2
3
4
5
6
7
8
9protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
File.AppendAllText("/var/log/netcoreservice.log",
$"Worker running at: {DateTimeOffset.Now}{Environment.NewLine}");
await Task.Delay(1000, stoppingToken);
}
}
安裝為 Services
發佈專案
或是建置(build),兩者輸出路徑不同,到時要建立 Services 時,指的路徑也不同。1
dotnet publish -o d:\Temp\workerpub
輸出1
2
3
4
5
6
7
8
9
10D:\GitHubRepo\net-core-3-windows-services>dotnet publish -o d:\Temp\workerpub
Microsoft (R) Build Engine for .NET Core 16.3.0-preview-19377-01+dd8019d9e 版
Copyright (C) Microsoft Corporation. 著作權所有,並保留一切權利。
D:\GitHubRepo\net-core-3-windows-services\net-core-3-windows-services.csproj 的還原於 26.1 ms 完成。
You are using a preview version of .NET Core. See: https://aka.ms/dotnet-core-preview
net-core-3-windows-services -> D:\GitHubRepo\net-core-3-windows-services\bin\Debug\netcoreapp3.0\net-core-3-windows-services.dll
net-core-3-windows-services -> d:\Temp\workerpub\
D:\GitHubRepo\net-core-3-windows-services>
安裝 Services
在以 系統管理員
權限執行的 命令提示字元中
,利用 windows 提供的 sc 命令安裝服務,命名為 “workertest”。binPath 參數則指向輸出的執行檔。1
sc create workertest binPath=D:\Temp\workerpub\net-core-3-windows-services.exe
結果
啟用 Services
1 | sc start workertest |
可觀察 /var/log/netcoreservice.log 更新的狀態。
Linux systemd 範例
利用 dotnet cli 建立服務專案
安裝 Systemd 套件
此時此刻,最新版本為 3.0.0-preview8.19405.41
dotnet add package Microsoft.Extensions.Hosting.Systemd --version 3.0.0-preview8.19405.4
啟用 Systemd 功能
增加 UseSystemd() 到 Program.cs 的 HostBuilder 中,以啟用 Systemd 功能。1
2
3
4
5
6
7public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSystemd()
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
});
實做功能
修改 Worker.cs 實做要提供的功能。
安裝為 Services
發佈專案
或是建置(build),兩者輸出路徑不同,到時要建立 Services 時,指的路徑也不同。1
sudo dotnet publish -o /usr/sbin/testapp
建立 .service 檔
要建立 Linux 的 service,需要在 /etc/systemd/system/ 目錄下提供一個 .service 檔做配置 service 之用。將服務命名為 testapp 時,檔名為 testapp.service,基本內容如下1
2
3
4
5
6
7
8
9[Unit]
Description=my test app
[Service]
Type=notify
ExecStart=/usr/sbin/testapp/net-core-3-linux-systemd
[Install]
WantedBy=multi-user.target
ExecStart 指到發佈路徑下的主程式
重載服務
1 | sudo systemctl daemon-reload |
啟用 Services
1 | sudo systemctl enable testapp.service |
執行 Services
1 | sudo systemctl enable testapp.service |
觀察 /var/log/netcoreservice.log 的內容。
1 | tail -f /var/log/netcoreservice.log |
完整範例專案
Windows Services
GitHub: .NET Core 3 的 Windows Services 範例
Linux systemd
GitHub: .NET Core 3 的 Linux systemd 範例