c# - register - windows service.net standard




.Net Core 2.0 Служба Windows (5)

Я пытаюсь построить службу Windows в .Net Core 2.0, но я ударяю головой о стену на целый день и никакого прогресса вообще. Все, кажется, использует Core 1.0 / 1.1 даже документацию Microsoft:

Узел приложения ASP.NET Core в службе Windows

TopShelf также не поддерживает 2.0, что я видел.

Я видел некоторые странные решения, которые поместили весь код в .Net Standard Class Library, а затем использовали приложение .NET Framework для размещения Windows Service, но это не выглядит элегантно в моих глазах, и я пытаюсь получить вообще избавиться от.NET Framework.

Является ли то, что я хочу сделать в данный момент? Я пропустил что-то действительно основное?


В .NET Core 2.1 вы можете использовать Host и HostBuilder для получения консольного приложения, которое работает как служба. Если вы контейнеризируете консольное приложение, вы можете развернуть контейнер в любом месте, и он будет таким же, как и работа с сервисом. Вы можете использовать Host и HostBuilder для управления DI, Logging, Graceful shut down и т. Д. В консольном приложении. Посмотри на:

Услуги хостинга в приложении консоли .NET Core


Возможно, это полная копия, но помните, что с большей поддержкой докеров вы можете создать службу, которая работает в контейнере. В этот момент это все равно будет .net core (2.0), но работает на вашем окне окна. Более того, вы могли бы развертывать практически в любом месте в будущем.

Поскольку ядро ​​dotnet созревает, я это лучшее и лучшее решение, предполагая, что ваша служба не требует ресурсов, локальных для хоста.


Поскольку Microsoft выпустила Microsoft.Windows.Compatibility, я бы использовал ее, поскольку она кажется лучшей для будущего использования.

Простой пример службы самостоятельной установки находится здесь https://github.com/janantos/service_core


Я подведу некоторые варианты:

  1. Переместите свой код в библиотеку .NET Standard и разместите его в приложении .NET Framework, чтобы вы могли использовать ServiceBase . Конечно, для этого потребуется установить .NET Framework на целевой машине
  2. Используйте nssm (диспетчер служб несоответствия) для управления консольным приложением .NET Core (у него есть лицензия для общедоступного домена)
  3. Используйте вызовы Windows API, чтобы подключиться к методам службы Windows. Это подход, используемый DotNetCore.WindowsService и github.com/dasMulli/dotnet-win32-service (оба лицензированы MIT)

Я думаю, что комментарий @ JeroenMostert немного суровый - я вижу, что привлекательность не зависит от конкретной версии .NET Framework, доступной на целевых компьютерах. Многие другие, очевидно, чувствуют то же самое, что и 2 репозиции, с которыми я связан, довольно популярны.


Теперь можно создать службу Windows в .NET Core 2.0 без сторонних библиотек, благодаря выпуску пакета совместимости Windows (на момент написания, все еще в предварительном порядке). Поскольку сама страница предупреждает:

Но прежде чем приступить к портированию, вы должны понять, чего хотите добиться при миграции. Просто портирование на .NET Core, потому что это новая реализация .NET, не является достаточно хорошей причиной (если вы не настоящий вентилятор).

В частности, теперь возможно создание службы Windows в .NET Core, но вы не получите межплатформенную совместимость из коробки, потому что сборки для платформ, отличных от Windows, будут просто бросать исключение PlatformNotSupportedException если вы попытаетесь использовать служебный код , Работа вокруг этого возможна (например, с использованием RuntimeInformation.IsOSPlatform ), но это другой вопрос.

Кроме того, сторонние библиотеки могут по-прежнему предлагать более удобный интерфейс для установки службы: 2.0.0-preview1-26216-02 с записи, текущая версия пакета совместимости ( 2.0.0-preview1-26216-02 ) не поддерживает System.Configuration.Install пространство имен, поэтому подход по умолчанию с классом ServiceProcessInstaller и installutil не будет работать. Об этом позже.

Учитывая все сказанное, предположим, что вы создали совершенно новый сервис Windows ( Service1 ) из шаблона проекта (строго не требуется, поскольку он не содержит ничего интересного, кроме класса, наследующего от 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>

И затем удалите properties\AssemblyInfo.cs поскольку он больше не требуется и будет конфликтовать с информацией о версии в самом проекте.

Если у вас уже есть служба, и у нее есть зависимости, преобразование может быть более сложным. См. here .

Теперь вы сможете запустить 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 или используя одну из библиотек, упомянутых в ответе Cocowalla .







asp.net-core