Topshelf注册windows服务,方便快捷
我们经常会用一些定时处理的任务,在.net种一般是结合Quartz或者hangfire这两个组件实现定时周期性作业,但是我想把开发好的定时作业注册成windows服务,这样,在服务器重启之后,可以自动运行服务。Topshelf 就可以很方便的开发windows,而且注册安装也很方便。
TopShelf的地址:http://topshelf-project.com/
我们首先使用netget安装TopShelf:
| 1
 | Install-Package TopShelf
 | 
然后在program.cs中加入如下代码:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 
 | var builder = new HostBuilder().ConfigureAppConfiguration(config =>
 {
 config.AddJsonFile("monitor.json", optional: true, reloadOnChange: true);
 })
 .ConfigureServices((hostContext, services) =>
 {
 services.Configure<Config>(hostContext.Configuration.GetSection("monitor"));
 services.AddSingleton<IHostLifetime, TopshelfLifetime>();
 services.AddHostedService<MonitorService>();
 
 
 });
 
 HostFactory.Run(service =>
 {
 
 service.SetServiceName("服务名");
 service.SetDisplayName("服务显示名称");
 service.SetDescription("服务描述");
 service.UseLog4Net("log4net.config");
 service.Service<IHost>(host =>
 {
 
 host.ConstructUsing(() => builder.Build());
 host.WhenStarted(serviceInstance =>
 {
 serviceInstance.StartAsync();
 });
 host.WhenStopped(serviceInstance =>
 {
 serviceInstance.StopAsync();
 });
 
 });
 service.OnException((ex) => {
 Console.WriteLine("Exception thrown - " + ex.Message);
 });
 service.RunAsLocalSystem();
 });
 
 
 }
 
 
 | 
新建一个类继承IHostedService接口:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 
 | public class MonitorService : IHostedService, IDisposable{
 private IScheduler scheduler;
 static readonly LogWriter _log = HostLogger.Get<MonitorService>();
 public readonly Config Config;
 
 private Timer _timer;
 Config _config;
 public MonitorService()
 {
 }
 public MonitorService(IOptions<Config> config)
 {
 
 _config = config?.Value;
 //Config = _config;
 }
 
 
 public async Task StartAsync(CancellationToken cancellationToken)
 {
 
 _log.Info("service starting");
 ISchedulerFactory sf = new StdSchedulerFactory();
 scheduler = await sf.GetScheduler();
 IJobDetail job = JobBuilder.Create<AreaSyncJob>().WithIdentity("job1", "group1").Build();
 ITrigger trigger = TriggerBuilder.Create().WithIdentity("triggger1", "group1").WithSchedule(CronScheduleBuilder.CronSchedule(new CronExpression(_config.AreaJobCronExpr))).Build();
 
 IJobDetail job1 = JobBuilder.Create<LocationSyncJob>().WithIdentity("job2", "group2").Build();
 ITrigger trigger1 = TriggerBuilder.Create().WithIdentity("triggger2", "group2").WithSchedule(CronScheduleBuilder.CronSchedule(new CronExpression(_config.LocationCronExpr))).Build();
 
 IJobDetail job2 = JobBuilder.Create<TaskExecAyncJob>().WithIdentity("job3", "group3").Build();
 ITrigger trigger2 = TriggerBuilder.Create().WithIdentity("triggger3", "group3").WithSchedule(CronScheduleBuilder.CronSchedule(new CronExpression(_config.TaskExecCronExpr))).Build();
 
 IJobDetail job3 = JobBuilder.Create<MonitorJob>().WithIdentity("job4", "group4").Build();
 ITrigger trigger3 = TriggerBuilder.Create().WithIdentity("triggger4", "group4").WithSchedule(CronScheduleBuilder.CronSchedule(new CronExpression(_config.MonitorCronExpr))).Build();
 
 //启动任务
 await scheduler.ScheduleJob(job, trigger);
 await scheduler.ScheduleJob(job1, trigger1);
 await scheduler.ScheduleJob(job2, trigger2);
 await scheduler.ScheduleJob(job3, trigger3);
 await scheduler.Start();
 _log.Info("service started");
 
 }
 
 
 
 public Task StopAsync(CancellationToken cancellationToken)
 {
 _timer?.Change(Timeout.Infinite, 0);
 scheduler?.Shutdown();
 return Task.CompletedTask;
 }
 
 public void Dispose()
 {
 scheduler = null;
 _timer?.Dispose();
 }
 }
 
 
 | 
StartAsync方法为服务启动时运行。然后编译程序:
| 1
 | dotnet publish -o ./bin/output -c Release -r win7-x64
 | 
执行成功后,会在bin/output目录下生成运行所需要的的程序和依赖DLL。将整个目录复制到指定服务器,cmd进入到程序目录,执行:
就可以完成服务安装.
执行:
就可以完成服务卸载,非常方便。