source

.Net Core 2.0 Windows 서비스

manycodes 2023. 8. 24. 22:15
반응형

.Net Core 2.0 Windows 서비스

에서 Windows 서비스를 구축하려고 합니다.Net Core 2.0 그러나 저는 하루 종일 벽에 머리를 부딪혔지만 전혀 진전이 없었습니다.마이크로소프트 설명서에서도 모든 것이 Core 1.0/1.1을 사용하고 있는 것 같습니다.

ASP를 호스팅합니다.윈도우즈 서비스의 NET Core 앱

가 본 바로는 TopShelf는 2.0도 지원하지 않습니다.

나는 모든 코드를 a에 넣는 이상한 해결책들을 보았습니다.Net Standard 클래스 라이브러리를 사용합니다.Windows 서비스를 호스팅하기 위한 NetFramework 응용 프로그램입니다. 하지만 이것은 제 눈에는 우아하게 보이지 않고 제거하려고 합니다.전체적으로 Net Framework.

지금 제가 하고 싶은 일이 가능할까요?제가 정말 기본적인 것을 놓치고 있는 건가요?

이제 에서 Windows 서비스를 작성할 수 있습니다.타사 라이브러리가 없는 NET Core 2.0은 Windows Compatibility Pack(작성 당시에는 여전히 사전 릴리스 중)의 릴리스 덕분입니다.페이지 자체에서 경고하는 바와 같이:

그러나 포팅을 시작하기 전에 마이그레이션으로 수행할 작업을 이해해야 합니다.그냥 에 포팅하는 중.새로운 것이기 때문에 NET Core.진정한 팬이 아니라면 NET 구현은 충분한 이유가 되지 않습니다.

특히 에서 윈도우즈 서비스를 작성합니다.는 이제는 NET Core를 할 수 얻을 수는 .PlatformNotSupportedException서비스 코드를 사용하려는 경우.이 문제를 해결하는 것이 가능합니다(사용)RuntimeInformation.IsOSPlatform예를 들어), 하지만 그것은 완전히 다른 질문입니다.

는 여전히 하여 더 할 수 현재 버전의 팩("pack")을 제공합니다.2.0.0-preview1-26216-02는 (으)를하지 않습니다.System.Configuration.Install즉 기본 은 " " " " " 입니다.ServiceProcessInstaller과 와스래클와▁andinstallutil작동하지 않습니다.그것에 대한 자세한 내용은 나중에.

이 완전히 Windows Windows 서비스, Windows 서비스)를 가정해 .Service1에서 (로부터로운 내용이 되어 있지 .ServiceBase한 모든 입니다. 2은 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더 이상 필요하지 않으며 프로젝트 자체의 버전 정보와 충돌하기 때문입니다.

서비스가 이미 있고 종속성이 있는 경우 변환이 더 복잡할 수 있습니다.여기 보세요.

이제도수겁니다있을칠망겁다를 실행할 수 .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코코왈라의 답변에 언급된 도서관 중 하나를 사용합니다.

호스트하기.윈도우즈 서비스로서의 NET Core 2.0 웹 API.저는 이 가이드 Host ASP를 따랐습니다.윈도우즈 서비스의 NET Core.전제 조건 부분은 저에게 명확하지 않습니다.몇 가지 실수 후에, 제가 한 일은 다음과 같습니다: 소스 코드

  1. ASP를 만듭니다.NET 코어 웹 애플리케이션
  2. API 선택
  3. .csproj 파일을 편집합니다. 대상 프레임워크를 netcoreapp 2.0에서 net461로 변경해야 합니다. Microsoft를 사용하지 않고 모든 패키지 참조를 명시적으로 나열합니다.AsNetCore.모두, 다음과 같이

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

  1. power shell [dot-folder] 도트넷 게시 -o [[dot-folder]]"
  2. power shell [sshell-folder] sc.exe CoreApi binpath=sshell-folder 생성\CoreApiHostedAsWindowsService.exe"
  3. 전원 셸 [solution-folder] sc.exe CoreApi 시작
  4. visit default api power shell [solution-folder] Invoke-WebRequest http://localhost:5000/api/values

몇 가지 옵션을 요약해 보겠습니다.

  1. 코드를 로 이동합니다.NET 표준 라이브러리를 호스트합니다.을 할 수 .ServiceBase이것은 당연히 필요할 것입니다.입니다. NET Framework
  2. NSSM(Non-Sucking Service Manager)을 사용하여 를 관리합니다.NET Core 콘솔 앱(퍼블릭 도메인 라이센스 있음)
  3. Windows API 호출을 사용하여 Windows 서비스 메서드에 연결합니다.이것은 DotNetCore가 취한 접근 방식입니다.Windows 서비스 및 dotnet-win32-service(둘 다 MIT 라이센스 있음)

저는 @Jeroen Mostert의 논평이 좀 가혹하다고 생각합니다 - 저는 특정한 것에 의존하지 않는다는 호소를 볼 수 있습니다.대상 시스템에서 사용할 수 있는 NET Framework 버전입니다.제가 링크한 2개의 저장소가 다소 인기가 있기 때문에 다른 많은 사람들도 분명히 동일하게 느끼고 있습니다.

.NET Core 2.1에서는 Host 및 Host Builder를 사용하여 서비스로 실행되는 콘솔 응용 프로그램을 가져올 수 있습니다.콘솔 응용 프로그램을 컨테이너화하면 컨테이너를 어디에나 배포할 수 있으며 이는 서비스로 실행되는 것과 동일합니다.Host 및 Host Builder를 사용하여 콘솔 앱에서 DI, 로깅, 정상 종료 등을 관리할 수 있습니다.다음 항목을 확인하십시오.

의 호스팅 서비스.NET Core 콘솔 애플리케이션

를 쉽게 생성할 수 있는 방법입니다.NET Core Windows 서비스는 Peter Kottas의 DotNetCore를 사용합니다.Windows 서비스 라이브러리.

NuGet 패키지는 Peter Kottas입니다.DotNetCore.Windows 서비스.Visual Studio Package Manager 콘솔을 사용하여 설치하려면 다음을 실행합니다.

Install-Package PeterKottas.DotNetCore.WindowsService

시작하는 방법에 대한 좋은 노트도 있습니다.

우리는 단지 시스템이 필요합니다.서비스 프로세스.서비스 컨트롤러 NuGet 패키지를 실행합니다.윈도우즈 서비스로서의 NET Core 애플리케이션.

다음은 .csproj 파일입니다.

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

<PropertyGroup>
  <OutputType>Exe</OutputType>
  <TargetFramework>netcoreapp2.1</TargetFramework>
  <RuntimeIdentifier>win7-x64</RuntimeIdentifier>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.ServiceProcess.ServiceController" 
 Version="4.5.0" />
</ItemGroup>

</Project>

Program.cs 파일,

using System.ServiceProcess;
namespace WindowsService101
{
class Program
{
    static void Main(string[] args)
    {
        using (var service = new HelloWorldService())
        {
            ServiceBase.Run(service);
        }
    }
}
}



public class HelloWorldService : ServiceBase
{
    protected override void OnStart(string[] args)
    {
       // Code Here
    }

    protected override void OnStop()
    {
        // Code Here
    }
}

솔루션을 구축하고 게시합니다.

  1. .exe 폴더 Sample: \윈도우즈Service101\bin\Debug\netcoreapp2에서 관리 모드로 cmd 프롬프트를 엽니다.1\colons

  2. sc create binPath=""

  3. sc start

의 ASP for 윈도의 ASP.NET 코어:.NET Core 2.2기존 ASP를 다음과 같이 변경합니다.앱을 서비스로 실행하기 위한 NET Core 프로젝트:

사항: 요구사:PowerShell 6.2 or later

프레임워크 종속 구축(FDD):

FDD(Framework-Dependent Deployment)는 의 시스템 전체 공유 버전에 의존합니다.대상 시스템의 NET Core.FDD 시나리오가 ASP와 함께 사용되는 경우.NET Core Windows Service 앱인 SDK는 프레임워크 종속 실행 파일(*.exe)을 생성합니다.

윈도우즈 RID(Runtime Identifier)를 에 추가합니다.<PropertyGroup>대상 프레임워크를 포함합니다.가 " " " " " " " " " 로 되어 있습니다.win7-x64추가합니다.<SelfContained>이 에설된재로 되었습니다.false이러한 속성은 SDK에 윈도우즈용 실행 파일(.exe)을 생성하도록 지시합니다.

일반적으로 ASP를 게시할 때 생성되는 web.config 파일입니다.윈도우즈 서비스 앱에는 NET Core 앱이 필요하지 않습니다.파일을 web.config 파일을 합니다.<IsTransformWebConfigDisabled>이 에설된재로 되었습니다.true.

<PropertyGroup>
  <TargetFramework>netcoreapp2.2</TargetFramework>
  <RuntimeIdentifier>win7-x64</RuntimeIdentifier>
  <SelfContained>false</SelfContained>
  <IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
</PropertyGroup>

SCD(Self-Contained Deployment):

SCD(Self-Contained Deployment)는 대상 시스템에 공유 구성 요소가 있는지 여부에 의존하지 않습니다.런타임 및 앱의 종속성은 앱과 함께 호스팅 시스템에 배포됩니다.

윈도우즈 RID(Runtime Identifier)가 있는지 확인하거나 RID를 에 추가합니다.<PropertyGroup>대상 프레임워크를 포함합니다.web.config 파일을 않도록 합니다.<IsTransformWebConfigDisabled>이 에설된재로 되었습니다.true.

<PropertyGroup>
  <TargetFramework>netcoreapp2.2</TargetFramework>
  <RuntimeIdentifier>win7-x64</RuntimeIdentifier>
  <IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
</PropertyGroup>

프로그램.메인

public class Program
{
    public static void Main(string[] args)
    {
        var isService = !(Debugger.IsAttached || args.Contains("--console"));

        if (isService)
        {
            var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
            var pathToContentRoot = Path.GetDirectoryName(pathToExe);
            Directory.SetCurrentDirectory(pathToContentRoot);
        }

        var builder = CreateWebHostBuilder(
            args.Where(arg => arg != "--console").ToArray());

        var host = builder.Build();

        if (isService)
        {
            // To run the app without the CustomWebHostService change the
            // next line to host.RunAsService();
            host.RunAsCustomService();
        }
        else
        {
            host.Run();
        }
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureLogging((hostingContext, logging) =>
            {
                logging.AddEventLog();
            })
            .ConfigureAppConfiguration((context, config) =>
            {
                // Configure the app here.
            })
            .UseStartup<Startup>();
}

FDD(Framework-Dependent Deployment) 게시:

dotnet publish --configuration Release --output c:\svc

SCD(자체 포함 배포) 게시

는 RID 에지합니에 .<RuntimeIdenfifier>(또는)<RuntimeIdentifiers>) 프로젝트 파일의 속성입니다.-r|--runtime 옵션에 런타임을 제공합니다.dotnet publishcommand

dotnet publish --configuration Release --runtime win7-x64 --output c:\svc

관리 PowerShell 6 명령 셸을 통해 icacls 명령을 사용하여 앱 폴더에 대한 쓰기/읽기/실행 액세스 권한을 부여합니다.

icacls "{PATH}" /grant "{USER ACCOUNT}:(OI)(CI){PERMISSION FLAGS}" /t
  • {PATH} – 앱의 폴더 경로입니다.
  • {USER ACCOUNT} – 사용자 계정(SID)입니다.
  • (OI) – Object Inherit 플래그는 사용 권한을 하위 파일로 전파합니다.
  • (CI) – Contain Inherit 플래그는 사용 권한을 하위 폴더로 전파합니다.
  • {PERMISSION FLARGS} – 앱의 액세스 권한을 설정합니다.
    • 쓰기( W)
    • 읽기( R)
    • 실행(X)
    • 전체(F)
    • 수정( M)
  • /t – 기존 하위 폴더 및 파일에 재귀적으로 적용합니다.

명령:

icacls "c:\svc" /grant "ServiceUser:(OI)(CI)WRX" /t

RegisterService.ps1 PowerShell 스크립트를 사용하여 서비스를 등록합니다.관리 PowerShell 6 명령 셸에서 다음 명령을 사용하여 스크립트를 실행합니다.

.\RegisterService.ps1 
    -Name MyService 
    -DisplayName "My Cool Service" 
    -Description "This is the Sample App service." 
    -Exe "c:\svc\SampleApp.exe" 
    -User Desktop-PC\ServiceUser

합니다.Start-Service -Name {NAME}PowerShell 6 버전.

Start-Service -Name MyService

시작 및 중지 이벤트 처리

internal class CustomWebHostService : WebHostService
{
    private ILogger _logger;

    public CustomWebHostService(IWebHost host) : base(host)
    {
        _logger = host.Services
            .GetRequiredService<ILogger<CustomWebHostService>>();
    }

    protected override void OnStarting(string[] args)
    {
        _logger.LogInformation("OnStarting method called.");
        base.OnStarting(args);
    }

    protected override void OnStarted()
    {
        _logger.LogInformation("OnStarted method called.");
        base.OnStarted();
    }

    protected override void OnStopping()
    {
        _logger.LogInformation("OnStopping method called.");
        base.OnStopping();
    }
}

확장 방법:

public static class WebHostServiceExtensions
{
    public static void RunAsCustomService(this IWebHost host)
    {
        var webHostService = new CustomWebHostService(host);
        ServiceBase.Run(webHostService);
    }
}

프로그램.주:

host.RunAsCustomService();

콘텐츠 루트 경로를 앱의 폴더로 설정합니다.

프로그램.주:

var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
var pathToContentRoot = Path.GetDirectoryName(pathToExe);
Directory.SetCurrentDirectory(pathToContentRoot);

CreateWebHostBuilder(args)
    .Build()
    .RunAsService();

출처:

https://github.com/aspnet/AspNetCore.Docs/tree/master/aspnetcore/host-and-deploy/windows-service/

https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/windows-service?view=aspnetcore-2.2

이것은 완전히 통제된 것일 수도 있지만, 도커 지원이 강화되면 컨테이너 내에서 실행되는 서비스를 구축할 수도 있습니다.이 시점에서도 .net core(2.0)이지만 Windows 박스에서 실행되고 있습니다.또한 미래에는 거의 모든 곳에 구축할 수 있습니다.

닷넷 코어가 성숙해짐에 따라 서비스에 호스트의 로컬 리소스가 필요하지 않다고 가정할 때 이 솔루션이 더 좋고 더 나은 솔루션이라고 생각합니다.

이 질문을 찾았지만 Windows 서비스를 구현하려는 사용자를 위한 질문입니다.NET Core 3.x

https://csharp.christiannagel.com/2019/10/15/windowsservice/

일반 호스트와 백그라운드 서비스, 명령줄 도구 검색의 조합으로 윈도우즈 서비스를 사용할 수 있습니다.

마이크로소프트가 마이크로소프트를 출시했을 때.창문들.호환성, 나중에 사용하는 것이 가장 좋을 것 같기 때문에 사용하겠습니다.

자동 설치 서비스의 간단한 예는 https://github.com/janantos/service_core 입니다.

언급URL : https://stackoverflow.com/questions/46561660/net-core-2-0-windows-service

반응형