使用.NET Core创建Windows服务(一) - 使用官方推荐方式
创建Windows服务来运行批处理任务或者运行后台任务,是一种非常常见的模式,但是由于云服务(Amazon Lambda,Azure WebJobs以及Azure Functions)的激增,你可能不会经常使用Windows服务了。个人而言,我非常喜欢使用Azure WebJobs,因为我可以直接编写一个控制台程序,而不需要考虑如何云中运行它,一个批处理文件可以将其装换成一个自动化任务,并且可以保证7*24小时的运行。 但是也许你还没有使用云服务,或者你有一堆要作为Windows服务运行的旧版应用程序需要转换为.NET Core,但是不能完全将他们转换为“无服务器”(serverless)应用。 那么这边文章就是适合你的。 在许多方面,.NET Core中的Windows服务和.NET Framework中的Windows服务完全相同。但是,在编写服务的时候,你可能会遇到一些小问题。此外,本文中,我们仅介绍“Microsoft”方式的Windows服务创建,在后续,我会继续介绍如何使用第三方库 安装由于Visual Studio没有提供创建Windows服务的模板,所以我们需要通过创建控制台程序的方式来创建一个Windows服务。 创建完成之后,我们需要安装一个Nuget程序包,这个程序包会将一些Windows特定的API添加到.NET Core中,这些API实际上已经在完整框架中提供了,但是其中许多是Windows特有的,例如Windows服务。因此,它们并没有包含在.NET Core的基础库中,但是可以通过将Nuget程序包的方式引入到.NET Core中。 Install-Package Microsoft.Windows.Compatibility 代码以上引入的Nuget程序包中,最让我们感兴趣的是 下面呢,我们将在代码中创建一个类,这个类负责将一些简单的日志输出到一个临时文件中。我们将使用这个例子来了解其中的原理。我们的代码如下: class LoggingService : ServiceBase { private const string _logFileLocation = @"C:tempservicelog.txt"; private void Log(string logMessage) { Directory.CreateDirectory(Path.GetDirectoryName(_logFileLocation)); File.AppendAllText(_logFileLocation,DateTime.UtcNow.ToString() + " : " + logMessage + Environment.NewLine); } protected override void OnStart(string[] args) { Log("Starting"); base.OnStart(args); } protected override void OnStop() { Log("Stopping"); base.OnStop(); } protected override void OnPause() { Log("Pausing"); base.OnPause(); } } 所以这里你会注意到,我们的类是继承了 如果我们想从 static void Main(string[] args) { ServiceBase.Run(new LoggingService()); } 以上就是全部代码。 服务部署在发布服务的时候,我们不可能仅依靠Visual Studio来构建我们所需要的服务,我们还需要专门针对Windows运行时进行构建。为此,我们需要在项目根目录的命令提示符下运行以下命令。注意,这里我们传入了一个 dotnet publish -r win-x64 -c Release 命令运行完毕之后,我们可以检查以下 现在我们可以将这个发布目录移动带其他的任何地方,但是现在我们就暂时使用当前的发布目录。 下一步,我们需要使用管理员角色打开一个命令提示符,然后输入一下命令。 sc create TestService BinPath=C:fullpathtopublishdirWindowsServiceExample.exe
运行之后,我们应该会得到以下结果。 [SC] CreateService SUCCESS 然后我们要做的就是启动服务。 sc start TestService 现在我们可以查看一下我们的日志文件,查看服务的运行情况。 如果想要停止并删除服务,我们可以使用一下命令。 sc stop TestService sc delete TestService 服务调试在这里,我真的认为,使用"Microsoft"的方式注定会失败。因为调试服务实在是太繁琐了。 首先,我们将 public void OnStartPublic(string[] args) { Log("Starting"); } protected override void OnStart(string[] args) { OnStartPublic(args); base.OnStart(args); } 但是至少我们可以做如下了事情了。 static void Main(string[] args) { var loggingService = new LoggingService(); if (true) //Some check to see if we are in debug mode (Either #IF Debug etc or an app setting) { loggingService.OnStartPublic(new string[0]); while(true) { //Just spin wait here. Thread.Sleep(1000); } //Call stop here etc. } else { ServiceBase.Run(new LoggingService()); } } 你的另一个选择是,在调试模式下进行项目发布,安装服务,然后附加调试器。实际上,这是Microsoft建议你使用的方式,但是我认为这简直一团糟。 后续实际上,我们可以在这里做一些其他非常有用的事情, 比如我们可以通过创建一个install.bat批处理文件来为我们运行SC Create命令。但我认为,上面我们看到的调试问题,已经让我不再想使用这种方式了。 幸运的是,有一个名为 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 如何使用Windows登录凭据进行代理身份验证使用C#
- windows – Python 3.2 Multiprocessing.Process没有运行目
- windows-server-2008 – 如果/ bin更改,我可以阻止IIS回收吗
- windows – CPU密集型线程智慧
- windows – 通过USB端口发送和接收数据
- 为什么在Windows上运行本地系统服务不好?
- windbg – 如何从DLL堆标记中受益?
- windows-server-2008 – 将Windows Server 2008(不是R2)的就
- 使用免费工具开发轻量级(无运行时)基于Windows的GUI应用程序
- windows – 隔离应用程序并检查它通过Internet发送的数据包
- 域名系统 – Windows 2012无法验证没有根区域的转
- windows-server-2012 – 远程桌面服务安装/执行模
- 3dmax2016卸载/安装失败/如何彻底卸载清除干净3d
- windows-server-2003 – Windows 2003上的Mercur
- 如何从托管DLL获取可执行文件路径
- RaspberryPI树莓派3B使用帮助
- 有没有办法让Windows重新加载驱动程序而不重启?
- .net – 将基于ECC的证书从Windows证书存储导入C
- window.location.replace和window.location.href
- windows-server-2008 – “Net Send”命令进入Mi