.net core使用Topshelf注册windows服务

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
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
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进入到程序目录,执行:

1
xxxx.exe install

就可以完成服务安装.
执行:

1
xxxx.exe uninstall

就可以完成服务卸载,非常方便。

You forgot to set the qrcode for Alipay. Please set it in _config.yml.
You forgot to set the qrcode for Wechat. Please set it in _config.yml.
You forgot to set the business and currency_code for Paypal. Please set it in _config.yml.
You forgot to set the url Patreon. Please set it in _config.yml.
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×