作者: Dotnet Core Tutorials
译者: Lamond Lu
译文: 使用. NET Core 创建 Windows 服务(二) - 使用 Topshelf 方式
使用. NET Core 创建 Windows 服务
使用微软推荐方式
使用 Topshelf 方式
在前一篇文章中, 我给大家介绍了, 如何基于微软推荐方式使用. NET Core 创建 Windows 服务. 我们发现使用这种方式, 我们很容易就可以搭建和运行一个 Windows 服务, 但是问题是使用这种方式, 代码调试将非常困难.
那么现在就是 Topshelf 出场的时候了. Topshelf 是一个. NET Standard 库, 它消除了在. NET Framework 和. NET Core 中创建 Windows 服务的那些麻烦.
安装
与微软推荐方式类似, 这里 Visual Studio 并没有提供一个基于 Topshelf 创建 Windows 服务的模板, 所以我们依然需要通过创建普通控制台程序的方式, 来创建一个 Windows 服务.
然后, 我们需要通过 Package Manager Console, 运行以下命令, 安装 Topshelf 类库.
Install-Package Topshelf
代码
下面我们就来使用 Topshelf 重构之前的服务代码.
- public class LoggingService : ServiceControl
- {
- private const string _logFileLocation = @"C:\temp\servicelog.txt";
- private void Log(string logMessage)
- {
- Directory.CreateDirectory(Path.GetDirectoryName(_logFileLocation));
- File.AppendAllText(_logFileLocation,
- DateTime.UtcNow.ToString() + ":" + logMessage + Environment.NewLine);
- }
- public bool Start(HostControl hostControl)
- {
- Log("Starting");
- return true;
- }
- public bool Stop(HostControl hostControl)
- {
- Log("Stopping");
- return true;
- }
- }
代码看起来是不是很简单?
这里我们的服务类继承了 ServiceControl 类(实际上并不需要, 但是这可以为我们的工作打下良好的基础). 我们必须实现服务开始和服务结束两个方法, 并且像以前一样记录日志.
在 Program.cs 文件的 Main 方法中, 我们要写的代码也非常的简单. 我们可以直接使用 HostFactory.Run 方法来启动服务.
- static void Main(string[] args)
- {
- HostFactory.Run(x => x.Service<LoggingService>());
- }
这看起来真是太简单了. 但这并不是 HostFactory 类的唯一功能. 这里我们还可以设置
服务的名称
服务是否自动启动
服务崩溃之后的重启时间
- static void Main(string[] args)
- {
- HostFactory.Run(x =>
- {
- x.Service<LoggingService>();
- x.EnableServiceRecovery(r => r.RestartService(TimeSpan.FromSeconds(10)));
- x.SetServiceName("TestService");
- x.StartAutomatically();
- }
- );
- }
这里其实能说的东西很多, 但是我建议你还是自己去看看 Topshelf 的文档, 学习一下其他的配置选项. 基本上你能使用 Windows 命令行完成的所有操作, 都可以使用代码来设置:
部署服务
和之前一样, 我们需要针对不同的 Windows 环境发布我们的服务. 在 Windows 命令提示符下, 我们可以在项目目录中执行以下命令:
dotnet publish -r win-x64 -c Release
现在我们就可以查看一下 bin\Release\netcoreappX.X\win-x64\publish 目录, 我们会发现一个编译好的 exe, 下面我们就会使用这个文件来安装服务.
在上一篇文章中, 我们是使用 SC 命令来安装 Windows 服务的. 使用 Topshelf 我们就不需要这么做了, Topshelf 提供了自己的命令行参数来安装服务. 基本上使用代码能完成的配置, 都可以使用命令行来完成.
你可以查看相关的文档:
- <http://docs.topshelf-project.com/en/latest/overview/commandline.html>
- WindowsServiceExample.exe install
这里 WindowsServiceExample.exe 是我发布之后的 exe 文件. 运行以上命令之后, 服务应该就正常安装了! 这里有一个小问题, 我经常发现, 即使配置了服务自动启动, 但是服务安装之后, 并不会触发启动操作. 所有在服务安装之后, 我们还需要通过以下命令来启动服务.
WindowsServiceExample.exe start
在生产环境部署的时候, 我的经验是在安装服务之后, 等待 10 秒钟, 再启动服务.
调试服务
当我们是使用微软推荐方式的时候, 我们会遇到了调试困难的问题. 大多数情况下, 无论是否在服务内部运行, 我们都不得不使用命令行标志,#IF DEBUG 指令或者配置值来实现调试. 然后使用 Hack 的方式在控制台程序中模拟服务.
因此, 这就是为什么我们要使用 Topshelf.
如果我们的服务代码已经在 Visual Studio 中打开了, 我们就可以直接启动调试. Topshelf 会模拟在控制台中启动服务. 我们应该能在控制台中看到以下的消息.
The TestService service is now running, press Control+C to exit.
这确实符合了我们的需求. 它启动了我们的服务, 并像真正的 Windows 服务一样在后台运行. 我们可以像往常一样设置断点, 基本上它遵循的流程和正常安装的服务一样.
我们可以通过 ctrl+c, 来关闭我们的应用, 但是在运行服务执行 Stop 方法之前, 它是不能被关闭的, 这使我们可以调试服务的关闭流程. 与调试指令和配置标志相比, 这要容易的多.
这里需要注意一个问题. 如果你收到的以下内容的消息:
The TestService service is running and must be stopped before running via the console
这意味着你尝试调试的服务实际上已经作为 Windows 服务被安装在系统中了, 你需要停止 (不需要卸载) 这个正在运行的服务, 才可以正常调试.
后续
在上一篇中, 有读者指出. NET Core 中实际上已经提供了一种完全不同的方式运行 Windows 服务. 它的实质是利用了 ASP.NET Core 中引入的 "托管服务" 模型, 并允许它们作为 Windows 服务来运行, 这真的是非常的棒.
来源: https://www.cnblogs.com/lwqlun/p/11625789.html