.Net Core 2.0 Windows服务

我正在尝试在.Net Core 2.0中构建一个Windows服务,但是我一直在墙上敲了一整天,没有任何进展。 一切似乎都使用Core 1.0 / 1.1甚至Microsoft文档:

在Windows服务中托管ASP.NET Core应用程序

就我所见, TopShelf也不支持2.0。

我已经看到一些奇怪的解决方案,将所有代码放在.Net标准类库中,然后使用.Net Framework应用程序来托管Windows服务,但这在我看来并不优雅,我试图获得完全摆脱.Net Framework。

我现在想要做什么呢? 我错过了一些非常基本的东西吗

由于Windows兼容包的发布(在撰写本文时,仍处于预发布阶段),现在可以在没有第三方库的情况下在.NET Core 2.0中编写Windows服务。 由于页面本身警告:

但在开始移植之前,您应该了解要通过迁移完成的任务。 只是移植到.NET Core,因为它是一个新的.NET实现不是一个足够好的理由(除非你是一个真正的粉丝)。

特别是,现在可以在.NET Core中编写Windows服务,但是您不会获得开箱即用的跨平台兼容性,因为如果您尝试使用服务代码,则Windows以外的平台的程序集将抛出PlatformNotSupportedException 。 可以解决这个问题(例如,使用RuntimeInformation.IsOSPlatform ),但这是另一个问题。

此外,第三方库可能仍然提供有关安装服务的更好的界面:从写入开始,当前版本的兼容包( 2.0.0-preview1-26216-02 )不支持System.Configuration.Install命名空间,因此使用ServiceProcessInstaller类和installutil的默认方法将不起作用。 稍后会详细介绍。

尽管如此,让我们假设您已经从项目模板创建了一个全新的Windows服务( Service1 )(不是严格要求的,因为除了从ServiceBaseinheritance的类之外它没有任何有趣的内容)。 要使其在.NET Core 2.0上构建,您需要做的就是使用新格式编辑和替换.csproj

   Exe netcoreapp20 win-x64      

然后删除properties\AssemblyInfo.cs因为它不再需要,并且会与项目本身的版本信息冲突。

如果您已经拥有服务且它具有依赖性,则转换可能会更复杂。 看到这里 。

现在您应该能够运行dotnet publish并获得可执行文件。 如前所述,您无法使用ServiceProcessInstaller类来安装服务,因此您必须手动完成

  • 注册服务使用的事件源;
  • 创造实际的服务。

这可以通过一些PowerShell来完成。 从包含已发布可执行文件的位置的提升提示符:

 $messageResourceFile = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\EventLogMessages.dll" New-EventLog -LogName Application -Source Service1 -MessageResourceFile $messageResourceFile sc.exe create Service1 binPath= (Resolve-Path .\WindowsService1.exe) 

这在几个方面并不理想:这会对消息资源文件的路径进行硬编码(我们应该确定它来自可执行文件和注册表中的运行时路径),并对服务名称和可执行文件进行硬编码名称。 您可能希望通过在Program.cs执行某些命令行解析来为项目提供自己的安装function,或者使用Cocowalla的答案中提到的库之一。

将.NET Core 2.0 Web API作为Windows服务托管。 我在Windows服务中遵循了本指南Host ASP.NET Core 。 先决条件部分对我来说不清楚。 在出现一些错误之后,我就是这样做的: 源代码

  1. 创建ASP.NET核心Web应用程序 在此处输入图像描述
  2. 选择API 在此处输入图像描述
  3. 编辑.csproj文件,需要将目标框架从netcoreapp2.0更改为net461 ,明确列出所有包引用而不是使用Microsoft.AspNetCore.All ,如下
   net461 win7-x64                   

我将总结一些选择:

  1. 将代码移动到.NET标准库中,并将其托管在.NET Framework应用程序中,以便您可以使用ServiceBase 。 这当然需要在目标机器上安装.NET Framework
  2. 使用NSSM (非吸吮服务管理器)来管理.NET Core控制台应用程序(它具有公共域许可证)
  3. 使用Windows API调用挂钩到Windows服务方法。 这是DotNetCore.WindowsService和dotnet-win32-service采用的方法 (两者都是MIT许可的)

我认为@JeroenMostert的评论有点苛刻 – 我可以看到不依赖于目标机器上可用的特定.NET Framework版本的吸引力。 很多其他人显然也有同感,因为我联系到的2个回购品很受欢迎。

在.NET Core 2.1中,您可以使用Host和HostBuilder来获取作为服务运行的控制台应用程序。 如果您将控制台应用程序容器化,则可以将容器部署在任何位置,它与作为服务运行时相同。 您可以使用Host和HostBuilder在您的控制台应用程序中管理DI,Logging,Graceful关闭等。 看一下:

.NET Core控制台应用程序中的托管服务

也许这是一个完整的伪造,但请记住,通过更大的docker支持,您可以构建一个在容器内运行的服务。 那时,它仍然是.net core(2.0),但在你的Windows框上运行。 更重要的是,您可以在将来的任何地方部署。

随着dotnet核心的成熟,我认为这是一个更好,更好的解决方案,假设您的服务不需要主机本地资源。

创建.NET Core Windows服务的一种简单方法是使用Peter Kottas的DotNetCore.WindowsService库 。

NuGet包是PeterKottas.DotNetCore.WindowsService 。 要使用Visual Studio包管理器控制台安装它,只需运行即可

 Install-Package PeterKottas.DotNetCore.WindowsService 

关于如何入门也有很好的说明 。

由于微软发布了Microsoft.Windows.Compatibility,我会使用它,因为它似乎最适合将来使用。

自安装服务的简单示例在https://github.com/janantos/service_core