十年河东,十年河西,莫欺少年穷
学无止境,精益求精
本篇博客演示控制台程序发布为windows服务,涉及依赖注入,配置文件读取,backGroundService,及 timer
1、新建控制台程序 MyWindowsService
2、添加Nuget引用 Microsoft.Extensions.Hosting、Microsoft.Extensions.Hosting.WindowsServices
3、新建类 MyService 并 继承自 BackgroundService
MyService继承BackgroundService 后,必须要重新实现ExecuteAsync方法,除了ExecuteAsync方法外,还有StartAsync 和 StopAsync 两个方法可用来重写
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Threading.Tasks; namespace MyWindowsService { public class MyService : BackgroundService { private readonly ILogger<MyService> _logger; System.Timers.Timer timer1; public MyService(ILogger<MyService> logger) { _logger = logger; } public override Task StartAsync(CancellationToken cancellationToken) { if (!cancellationToken.IsCancellationRequested) { timer1 = new System.Timers.Timer(); timer1.Interval = 1000 * 1; //设置计时器事件间隔执行时间 每隔1秒执行一次 timer1.Elapsed += new System.Timers.ElapsedEventHandler(timer1_Elapsed); timer1.Enabled = true; } return base.StartAsync(cancellationToken); } /// <summary> /// 每一秒执行一次 /// </summary> /// <param name="stoppingToken"></param> /// <returns></returns> protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { var now = DateTime.Now; Console.WriteLine("ExecuteAsync执行结果:" + now); await Task.Delay(1000, stoppingToken); } // if (!stoppingToken.IsCancellationRequested) { //只执行一次 var now = DateTime.Now; Console.WriteLine("ExecuteAsync执行结果:" + now); await Task.Delay(1000, stoppingToken); } if (stoppingToken.IsCancellationRequested) { //不使用ExecuteAsync ,使用自定义的timer1 var now = DateTime.Now; Console.WriteLine("ExecuteAsync执行结果:" + now); await Task.Delay(1000, stoppingToken); } } public override Task StopAsync(CancellationToken cancellationToken) { timer1.Enabled = false; return base.StopAsync(cancellationToken); } private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { var now = DateTime.Now; Console.WriteLine("timer1_Elapsed执行结果:" + now); } } }
4、添加appsettings.json文件
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "myKey": "hello windows service" }
5、Program.cs代码如下
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using System; namespace MyWindowsService { internal class Program { static void Main(string[] args) { CreateHostBuilder(args).Run(); } public static IHost CreateHostBuilder(string[] args) { var builder = Host.CreateDefaultBuilder(args) .ConfigureServices((hostContext, services) => { services.AddTransient<ITestD1, TestD1>(); services.AddHostedService<MyService>(); }).ConfigureAppConfiguration((hostContext, configApp) => { configApp.AddJsonFile("appsettings.json"); }).UseWindowsService(); var host = builder.Build(); using (var serviceScope = host.Services.CreateScope()) { var services = serviceScope.ServiceProvider; var myConfig = services.GetRequiredService<IConfiguration>(); Console.WriteLine(myConfig.GetSection("mykey")); //其他类中获取 var myService = services.GetRequiredService<ITestD1>(); Console.WriteLine(myService.GetConfig("mykey")); // } return host; } } public interface ITestD1 { string GetConfig(string key); } public class TestD1 : ITestD1 { /// <summary> /// 配置信息 /// </summary> private readonly IConfiguration _configuration; /// <summary> /// 构造函数的方式进行依赖注入 /// </summary> /// <param name="configuration"></param> public TestD1(IConfiguration configuration) { _configuration = configuration; } public string GetConfig(string key) { return _configuration.GetSection(key).Value; } } }
6、发布控制台程序为windows服务
以管理员身份运行 cmd,打开cmd 窗口
执行如下命令
sc create MyWindowsService binPath="E:\Project\WuAnPolice\MyWindowsService\bin\Debug\netcoreapp3.1\MyWindowsService.exe" DisplayName="MyWindowsService" start=auto
然后到服务中去找 MyWindowsService,启动服务即可
7、删除windows服务
将要删除的服务重置为禁用状态,然后执行如下指令
sc delete MyWindowsService