.NET 6學習筆記(2)——通過Worker Service創建Windows Service

通過Visual Studio中的Windows Service模板,我麼可以創建.NET Framework版本的Windows Service,網絡上對此已有詳細且豐富的各路教程。但在我們升級到.NET Core 3.1或.NET 6後(這裏僅討論兩個LTS版本),情況發生了相當大的變化。我們需要根據新的Worker Service模板,基於BackgroundService這個類來創建最新版本的Windows Service。

某軟的官方文檔更新的很快,文檔中列出的創建Windows Service的必要條件都已經是6.0或更新。那是不是說.NET Core 3.1就無法創建呢?答案當然不是。今天我們就稍作修改,創建3.1版本的Windows Service。

.NET Core 3.1作爲LTS(Long-term support)版本,是存在大量基於該版本的生產項目的,有時候條件不允許立刻升級到VS2022和.NET 6.0。所以本篇我們將使用VS2019,首先找到Worker Service模板,如果我們仔細觀察,會發現除了Windows平臺,更多了Linux和macOS的支持。

點擊兩次Next按鈕後,選擇.NET Core 3.1版本創建工程。默認僅包含Program和Worker兩個cs文件。接下來我們通過NuGet安裝Microsoft.Extensions.Hosting.WindowsService包。最新的版本是6.0,且同時依賴6.0版的Microsoft.Extension.Hosting。這裏我們有兩個選擇,第一是在NuGet界面的下拉框中,選擇安裝3.1.17版本的WindowsService包,保持和默認Hosting包的版本相同。第二是將兩者都升級到最新的6.0版本。所幸.NET的向後兼容做的不錯,在這裏我選擇升級。在完成後的簡單測試中,無論是部署在.NET 6 Runtime或.NET Core 3.1 Runtime的機器上,均可正常工作。當前狀態應該如下圖所示。

此時我們可以開始創建業務類了,就是你想用Service乾點啥,在本篇的示例中,我只想躺平……疫情期間,不要用眼過度和上頭648充值抽卡,打遊戲實在是極其健康的選擇了。

    public class LieFlatService
    {
        public static int Count { get; set; }
        public string LieFlat()
        {
            return $"Lie flat and play PS4 & Switch... {++Count}";
        }
    }

接着我們通過繼承自BackgrounService的Worker類來調用LieFlatService實現躺平。真的是啥也不幹,就是每隔一秒宣告一下躺平。

    public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;
        private readonly LieFlatService _lieFlatSrvice;

        public Worker(LieFlatService lieFlatService, ILogger<Worker> logger)
        {
            _lieFlatSrvice = lieFlatService;
            _logger = logger;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                string message = _lieFlatSrvice.LieFlat();
                _logger.LogWarning(message);
                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                await Task.Delay(1000, stoppingToken);
            }
        }
    }

然後我們還要修改一下Program類,通過UseWindowsService擴展方法將我們這個Console程序配置成Windows Service類型。如果我們之前選擇WindowsServices 3.1的包,除了不能方便的設置SeviceName,其他倒是沒啥區別。在CreateHostBuilder方法中,記得註冊Worker和LieFlatService類型供.NET內置的依賴注入(Dependency Injection)框架使用。

    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args)
                .UseWindowsService(o =>
            {
                o.ServiceName = "Lie Flat Service";
            })
                .Build()
                .Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddHostedService<Worker>();
                    services.AddSingleton<LieFlatService>();
                });
    }

代碼部分至此就全部完成了。相對於.NET Framework的Windows Service,調試起來要容易的多,就直接當成Console程序Debug就行了。部署的操作也很簡單,首先在project文件上右鍵選擇發佈到文件夾。

通常默認的發佈配置就可以了,點擊發布按鈕之後,會在項目的bin\Release\netcoreapp3.1\win-x64\publish\目錄下生成如下文件。如果修改發佈文件選擇Self Contained,則可以脫離對部署環境是否安裝.NET的依賴,缺點就是會生成一大堆文件。

我們可以將publish文件夾拷貝到想要的位置,然後用admin權限打開PowerShell,通過命令行來創建Windows Service。

sc.exe create "Lie Flat Service" binpath="C:\Users\dell\Desktop\publish\NetCoreWorkerService.exe"

此時打開Services界面,將創建的Lie Flat Service啓動。

再打開Event Viewer檢查Windows Logs,就可以發現Lie Flat Service發出的躺平宣言了。

刪除Windows Service需要通過stop和delete兩個命令。

本篇我們介紹瞭如何在.NET Core 3.1(.NET 6.0也幾乎相同)的環境下創建Windows Service。同時.NET 4.5.2, .NET 4.6和.NET 4.6.1將於2022年4月26日終止支持。升級吧同學們。

示例代碼:

https://github.com/manupstairs/NetCoreWorkerService

manupstairs/WorkerServiceTest1 (gitee.com)

以下鏈接,是MS Learn上Windows開發的入門課程,單個課程三十分鐘到60分鐘不等,想要補充基礎知識的同學點這裏:

開始使用 Visual Studio 開發 Windows 10 應用

開發 Windows 10 應用程序

編寫首個 Windows 10 應用

創建 Windows 10 應用的用戶界面 (UI)

增強 Windows 10 應用的用戶界面

在 Windows 10 應用中實現數據綁定

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章