.NET 6 中将 ASP.NET Core 注册成 Windows Service

前言

使用 Visual Studio 中的 Worker Service项目模板

.NET 6 中将 ASP.NET Core 注册成 Windows Service

我们很容易创建出 Windows Service:.

IHost host = Host.CreateDefaultBuilder(args)  
    .UseWindowsService()  
    .ConfigureServices(services =>  
    {  
        services.AddHostedService<Worker>();  
    })  
    .Build();  
  
await host.RunAsync();  

_需要引用 NuGet 包Microsoft.Extensions.Hosting.WindowsServices_但是,当我们想把 ASP.NET Core 应用注册成 Windows Service 时,却碰到了一些麻烦。

Demo

创建 ASP.NET Core 应用,然后把 Worker Service 中的代码复制过来:

var builder = WebApplication.CreateBuilder(args);  
  
builder.Host.UseWindowsService()  
.ConfigureServices(services =>  
{  
    services.AddHostedService<Worker>();  
});  
  
var app = builder.Build();  
  
app.MapGet("/", () => "Hello MyIO!");  
  
app.Run();  

需要注意的是:与 Worker Service 不同,在 ASP.NET Core 应用中,需要通过builder.Host拿到IHostBuilder的实例。

使用sc create注册 Windows Service 成功。但是在启动时,却提示 1053 错误:

.NET 6 中将 ASP.NET Core 注册成 Windows Service

通过事件查看器,我们发现导致错误的原因是当前工作目录是C:\WINDOWS\system32而不是我们的 ASP.NET Core 应用所在目录:

.NET 6 中将 ASP.NET Core 注册成 Windows Service

解决方案

1、修改工作目录

虽然在 Windows Service 属性窗口中不能设置工作目录,但是我们可以在启动时修改当前工作目录:

Directory.SetCurrentDirectory(AppContext.BaseDirectory);  
  
var builder = WebApplication.CreateBuilder(args);  

2、设置 ContentRootPath

既然是ContentRootPath不正确导致的错误,那我们就按照错误提示使用 WebApplicationOptions 设置正确的ContentRootPath即可:

var builder = WebApplication.CreateBuilder(new WebApplicationOptions  
{  
    ContentRootPath = AppContext.BaseDirectory,  
    Args = args  
});  

结论

通过 2 种解决方案,我们都可以成功将 ASP.NET Core 应用注册成 Windows Service 并运行。