.Net Core 2.0 Windows Service

前端 未结 10 1355
谎友^
谎友^ 2021-01-30 01:25

I\'m trying to build a Windows Service in .Net Core 2.0 but I\'ve been banging my head on the wall for a full day and no progress at all. Everything seems to be using Core 1.0/1

10条回答
  •  一向
    一向 (楼主)
    2021-01-30 02:17

    It is now possible to write a Windows Service in .NET Core 2.0 without third-party libraries, thanks to the release of the Windows Compatibility Pack (at the time of writing, still in prerelease). As the page itself warns:

    But before you start porting, you should understand what you want to accomplish with the migration. Just porting to .NET Core because it's a new .NET implementation isn't a good enough reason (unless you're a True Fan).

    In particular, writing a Windows Service in .NET Core may now be possible, but you will not get cross-platform compatibility out of the box, because the assemblies for platforms other than Windows will just throw a PlatformNotSupportedException if you attempt to use service code. Working around this is possible (using RuntimeInformation.IsOSPlatform, for example), but that's another question altogether.

    Also, third-party libraries may still offer a nicer interface with regards to installing the service: as of writing, the current version of the compatibility pack (2.0.0-preview1-26216-02) does not support the System.Configuration.Install namespace, so the default approach with a ServiceProcessInstaller class and installutil will not work. More on that later.

    With all that said, let's suppose you have created a brand new Windows service (Service1) from the project template (not strictly required since it contains nothing interesting, other than a class inheriting from ServiceBase). All you need to do to make it build on .NET Core 2.0 is to edit and replace the .csproj with the new format:

    
      
        Exe
        netcoreapp20
        win-x64
      
      
        
      
    
    

    And then delete properties\AssemblyInfo.cs since it's no longer required and will conflict with version information in the project itself.

    If you already have a service and it has dependencies, the conversion may be more complicated. See here.

    Now you should be able to run dotnet publish and get an executable. As mentioned, you can't use the ServiceProcessInstaller class to install the service, so you'll have to manually

    • register the event source the service uses;
    • create the actual service.

    This can be done with some PowerShell. From an elevated prompt in the location that contains your published executable:

    $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)
    

    This is not ideal in several ways: this hard-codes the path of the message resource file (we should really be determining where it is from the executable and the runtime paths in the registry), and it hard-codes the service name and executable name. You may want to give your project its own installation capabilities by doing some command-line parsing in Program.cs, or use one of the libraries mentioned in Cocowalla's answer.

提交回复
热议问题