參考文章https://www.cnblogs.com/RainFate/p/12095793.html
Topshelf
Topshelf 是一個用來部署基於.NET Framework 開發的服務的框架。簡化服務創建於部署過程,並且支持控制台應用程序部署為服務。本文基於 .net core 控制台應用程序部署為服務(.net Framework 可用)。
第一步:創建名為 TopshelfDemo 的控制台應用程序。
第二步:通過 Nuget 安裝 Topshelf 包。
第三步:Toshelf 配置,代碼並不多下面都有注釋。
using System; using Topshelf; namespace TopshelfDemo { class Program { static void Main(string[] args) { try { // 配置和運行宿主服務 HostFactory.Run(x => //1 { x.Service<Service>(s => //2 { // 指定服務類型。這里設置為 Service s.ConstructUsing(name => new Service()); //3 // 當服務啟動后執行什么 s.WhenStarted(tc => tc.Start()); //4 // 當服務停止后執行什么 s.WhenStopped(tc => tc.Stop()); //5 }); // 服務用本地系統賬號來運行 x.RunAsLocalSystem(); //6 // 服務描述信息 x.SetDescription("我的項目服務"); //7 // 服務顯示名稱 x.SetDisplayName("MyProjectServiceShowName"); //8 // 服務名稱 x.SetServiceName("MyProjectService"); //9 }); } catch (Exception ex) { Console.WriteLine(ex); } } } public class Service { public void Start() { //To do something } public void Stop() { //To do something } } }
第四步:安裝服務
確保項目正常生成,然后通過管理員權限打開 cmd 命令窗口,找到項目所在的 Debug 目錄,輸入命令:TopshelfDemo.exe install。
如果是使用 .net core 的小伙伴你會發現 Debug下壓根沒有 TopshelfDemo.exe ,這不是扯淡呢么,別急往下看。
由於 .net core 依賴 runtimes 所以我們需要發布以下程序,並且選擇獨立項目就ok啦。
這時你在布后的路徑下就可以找到 TopshelfDemo.exe 啦。
這時服務就安裝完畢了,我們可以通過 Windows 服務中查看。
刪除服務命令:TopshelfDemo.exe uninstall
也可以通過 sc delete MyProjectService 進行刪除
Worker Service
ASP.NET Core 3增加了一個非常有意思的功能Worker Service.他是一個ASP.NET Core模板,他允許我們創建托管長期的運行的后台服務,這些服務具體實現IHostedService接口的后台任務邏輯,他被成為"托管服務".同時他們可以部署到windows中Windows服務,以及Linux守護程序.
創建一個托管服務
您需要在您的環境中安裝Visual Studio 2019和.NET Core 3.0。
首先,您需要創建一個新項目,並選擇下圖所示的工作流程模板:
Program.cs:
public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureServices((hostContext, services) => { services.AddHostedService<Worker>(); }); }
Worker:
BackgroundService是實現了IHostedService的基類.調用 ExecuteAsync(CancellationToken) 來運行后台服務。實現返回一個Task,其表示后台服務整個生存期.在 ExeuteAsync(例如通過調用await)之前,不會啟動任何其他服務.避免在ExecuteAsync中執行長時間的阻塞初始化. StopAsync(CancellationToekn) 中的主機塊等待完成ExecuteAsync。
調用 IHostedService.StopAsync 時,將觸發取消令牌。 當激發取消令牌以便正常關閉服務時,ExecuteAsync 的實現應立即完成。 否則,服務將在關閉超時后不正常關閉。
using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace WorkerServiceDemo { public class Worker : BackgroundService { private readonly ILogger<Worker> _logger; public Worker(ILogger<Worker> logger) { _logger = logger; } public override async Task StartAsync(CancellationToken cancellationToken) { await base.StartAsync(cancellationToken); } public override async Task StopAsync(CancellationToken cancellationToken) { await base.StopAsync(cancellationToken); } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); await Task.Delay(1000, stoppingToken); } } public override void Dispose() { } } }
已使用AddHostedService擴展方法在 IHostBuilder.ConfigureServices(Program.cs)中注冊該服務。
services.AddHostedService<Worker>();
WorkerServices部署到Windows服務
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace WorkerServiceDemo { public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) { return Host.CreateDefaultBuilder(args) .ConfigureServices((hostContext, services) => { services.AddHostedService<Worker>(); }).UseWindowsService(); ; } } }
現在我們可以部署我們的windows服務了。
發布方式
- 使用sc.exe工具
- 直接部署exe文件
發布Windows服務
dotnet restore
dotnet publish
sc.exe部署
sc.exe create DemoWorker binpath= publish\xxxx.exe
sc.exe start WorkerServicesName
部署exe文件
WorkerServicesName.exe install
WorkerServicesName.exe start
使用sc.exe停止和刪除
sc.exe stop WorkerServicesName
sc.exe delete WorkerServicesName
非sc.exe停止和刪除
WorkerServicesName stop
WorkerServicesName uninstall
在Linux設置守護程序
將UseSystemd()添加上。
public static IHostBuilder CreateHostBuilder(string[] args) { return Host.CreateDefaultBuilder(args) .ConfigureServices((hostContext, services) => { services.AddHostedService<Worker>(); }).UseSystemd(); }
在Linux上設置為守護程序。
Reference
https://github.com/hueifeng/BlogSample/tree/master/src/WorkerServiceDemo