.Net Core 2.0 Windows服务

DGa*_*par 46 .net c# asp.net asp.net-core

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

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

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

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

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

Jer*_*ert 27

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

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

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

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

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

<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp20</TargetFramework>
    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Windows.Compatibility" Version="2.0.0-*" />
  </ItemGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)

然后删除,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)
Run Code Online (Sandbox Code Playgroud)

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


Che*_*ger 14

将.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,如下

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net461</TargetFramework>
    <RuntimeIdentifier>win7-x64</RuntimeIdentifier>
    <!--<TargetFramework>netcoreapp2.0</TargetFramework>-->
  </PropertyGroup>

  <ItemGroup>
    <Folder Include="wwwroot\" />
  </ItemGroup>

  <ItemGroup>
    <!--<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.6" />-->
    <PackageReference Include="Microsoft.AspNetCore" Version="2.0.2" />
    <PackageReference Include="Microsoft.AspNetCore.Hosting.WindowsServices" Version="2.0.2" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.3" />
    <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.2" />
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.1" />
    <PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="2.0.2" />
  </ItemGroup>

  <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.3" />
  </ItemGroup>

</Project>
Run Code Online (Sandbox Code Playgroud)

  1. power shell [solution-folder] dotnet publish -o"[publish-folder]"
  2. power shell [solution-folder] sc.exe create CoreApi binpath ="[publish-folder]\CoreApiHostedAsWindowsService.exe"
  3. power shell [solution-folder] sc.exe启动CoreApi
  4. 访问默认的api power shell [solution-folder] Invoke-WebRequest http:// localhost:5000/api/values

  • 在我的情况下,我不希望它主持一个WebSite,我只是希望它运行一些后台任务,如压缩一些文件,并通过FTP和其他一些东西上传它们,你会重新调查,这将工作吗? (4认同)

Coc*_*lla 12

我将总结一些选择:

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

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


Pet*_*ter 9

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

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