由于 IHostBuilder 上的额外扩展方法,无法启动 windows 服务(.Net Core worker 服务)

Cannot start windows service (.Net Core worker service) due to extra extension methods on IHostBuilder

目标: 我正在尝试 运行 .Net Core 3.1 Worker 服务作为 windows 服务。

设置: 我通过 Visual Studio.

使用了 Worker 服务默认模板

要为此添加 windows 服务功能,我安装了 Microsoft.Extensions.Hosting.WindowsServices nuget,然后按如下方式添加 .UseWindowsService()

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .UseWindowsService()
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddHostedService<Worker>();
                })
                ;

此后,可以通过以下方式成功启动服务:

sc create <WorkerSvcName> binPath=<C:/local/path/to/exe>
sc start <WorkerSvcName>

问题: 但是,我需要在 IHostBuilder 上使用进一步的扩展方法,例如 ..UseSerilog()。当我这样做时,除了上述设置之外,我总是得到:

[SC] StartService FAILED 1053:

The service did not respond to the start or control request in a timely fashion.

我试过的: 这适用于所有以下配置:

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                X
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddHostedService<Worker>();
                })
                X
                .UseWindowsService()
                X

以及:

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                X
                .UseWindowsService()
                X
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddHostedService<Worker>();
                })
                X
                ;

其中 X 是 IHostBuilder 上的自定义扩展方法:

public static IHostBuilder UseSerilog(this IHostBuilder builder)
    {
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

        builder.UseSerilog((context, services, configuration) =>
        {
           //do stuff


            configuration
                .ReadFrom.Configuration(config)
                .ReadFrom.Services(services)
                
        });
        Log.Information("Serilog has been configured");

        return builder;
    }

上面的替代位置告诉我这可能与 CreateHostBuilder() 中的配置顺序无关。

问题:关于为什么我不能使用任何其他扩展方法并继续运行宁windows服务有什么想法吗?

结果证明这是一次光荣的浪费时间,因为我有一段时间一直在寻找错误的地方。但它确实指出了一种从失败的 windows 服务中获取日志的巧妙方法。

我在 appsettings.json 中的 Serilog 部分看起来像:

  "Serilog": {
    "Using": [
      "Serilog.Sinks.Console",
      "Serilog.Sinks.File",
      "Serilog.Sinks.Async",
      "Serilog.Sinks.Elasticsearch",
      "Serilog.Sinks.ApplicationInsights",
      "Serilog.Sinks.NewRelic.Logs"
    ],
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Warning",
        "Microsoft.Hosting.Lifetime": "Information"
      }
    },
    "WriteTo": [
      {
        "Name": "Console",
        "Args": {
          .....
      },
      {
        "Name": "Async",
        "Args": {
          "configure": [
            {
              "Name": "File",
              ..........
        }
      },
      {
        "Name": "Elasticsearch",
        "Args": {
          .......
        }
      },
      {
        "Name": "ApplicationInsights",
        "Args": {
          .......
        }
      },
      {
        "Name": "NewRelicLogs",
        "Args": {
          "applicationName": "<val>",
          "licenseKey": "<val>" <-----------------THIS LINE WAS MISSING!!!!!!!
        }
      }
    ]

确实有关于此的日志 - 它只是不在 windows 服务控制台 window 中或通过 Visual Studio 的 IIS Express 配置文件打开的控制台。

要查找失败的 windows 服务的日志,请尝试以下方法:

  1. 通过 Visual Studio 将应用程序发布到本地文件夹。
  2. 通过命令提示符和 运行 .exe 进入上述文件夹以执行应用程序

生成的日志为我节省了时间。不确定为什么当 运行在调试或发布模式下时这些不会出现在控制台上。