Topshelf注册windows服务,方便快捷
我们经常会用一些定时处理的任务,在.net种一般是结合Quartz或者hangfire这两个组件实现定时周期性作业,但是我想把开发好的定时作业注册成windows服务,这样,在服务器重启之后,可以自动运行服务。Topshelf 就可以很方便的开发windows,而且注册安装也很方便。
TopShelf的地址:http://topshelf-project.com/
我们首先使用netget安装TopShelf:
1
| Install-Package TopShelf
|
然后在program.cs中加入如下代码:
1 2 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接口:
1 2 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进入到程序目录,执行:
就可以完成服务安装.
执行:
就可以完成服务卸载,非常方便。