【背景】我们有几个历史产品,需要部署在Windows系统上,产品有jar包,也有.net工程,为了优美的启动服务,思考了两种处理方式。
第一种是电脑开机启动,将启动命令设置为快捷键,并将快捷键拷贝到C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup目录下,该方式有个缺点,由于jar包启动方式都是使用javaw启动,当一个windows中有多个jar包已这种方式开机启动,在进程中无法区分是哪个服务,导致更包时需要全部重启。
第二种是将后台软件部署成windows服务,本文以真实的案例指导实现方式,参考:使用WinSW将nacos安装为windows服务;参考:使用.NET Core创建Windows服务详细步骤
【实践1】使用WinSW将jar创建成Windows服务
关键要素:
序号 |
模块 |
文件名 |
描述 |
1 |
work-service |
work-install.bat |
安装服务 |
2 |
work-uninstall.bat |
删除服务 |
|
3 |
work-service.exe |
Winsw服务(将winsw服务修改便于识别) |
|
4 |
work-service.xml |
服务配置 |
1、下载WinSW:https://github.com/winsw/winsw/releases,下载版本:WinSW v2.12.0->WinSW-x64.exe,17.4MB
2、准备配置,将以下四个文件与jar放在同一个目录下
(1)WinSW-x64.exe修改为work-service.exe,即以系统服务命名
(2)新建服务配置文件:work-service.xml
<service> <id>work-service</id> <name>work-service</name> <description>work服务</description> <executable>java</executable> <arguments>-server -Xms1024m -Xmx1024m -XX:PermSize=256m -XX:SurvivorRatio=2 -XX:+UseParallelGC -jar .\work.jar --spring.config.location=application.yml</arguments> <logpath>logs</logpath> <startmode>Automatic</startmode> </service>
(3)新建安装服务文件:work-install.bat
work-service.exe install work-service.exe start
(4)新建卸载服务文件:work-uninstall.bat
work-service.exe stop work-service.exe uninstall
3、执行操作
(1)鼠标双击work-install.bat,创建服务,并启动,可以在系统->服务中查询到服务名称为work-service的服务。
(2)鼠标双击work-uninstall.bat,停止并删除服务,系统->服务中work-service被删除了。
【实践2】使用Microsoft.Extensions.Hosting.WindowsServices将.net转换成Windows服务
该方式需要引入包Microsoft.Extensions.Hosting.WindowsServices,同时在Program.cs中添加UseWindowsService方法调用,
本文以work-service服务为例子:
(1)源码修改如下
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using System; using System.Net; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using log4net; namespace WorkServer { static class Program { public static readonly ILog Log = LogManager.GetLogger(typeof(Program)); static async Task Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) { var host = Host.CreateDefaultBuilder(args); //判断当前系统是否为windows if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { host.UseWindowsService(); } return host.ConfigureServices((hostContext, services) => { services.AddHostedService<Worker>(); }); } } public class Worker : BackgroundService { public static readonly ILog Log = LogManager.GetLogger(typeof(Worker)); private readonly ILogger<Worker> _logger; public Worker(ILogger<Worker> logger) { _logger = logger; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { try { //TODO 业务代码 while (!stoppingToken.IsCancellationRequested) { //TODO 业务代码 Log.Info("Worker running at: {DateTimeOffset.Now}"); await Task.Delay(1000, stoppingToken); } } catch (Exception e) { Log.Error("main:ExecuteAsync failed.", e); } } } }
(2)新建安装服务文件:work-install.bat
@sc create work-service binPath= "D:\work\WorkServer.exe"
@sc start work-service
@sc config work-service start= AUTO
(3)新建卸载服务文件:work-uninstall.bat
@sc stop work-service
- Windows WindowsServices Extensions Microsoft Hostingwindows windowsservices extensions microsoft dependencyinjection extensions microsoft castle dependenyinjection extensions microsoft castle extensions microsoft wpf extensions microsoft框架logging extensions microsoft logging core 第三方extensions microsoft logging 文件configuration extensions microsoft microsoft windows store microsoft故障windows系统