Worker Service 在 System32 文件夹而不是本地文件夹中寻找 appsettings.json

Worker Service looking for appsettings.json in System32 folder instead of local folder

我有一个 .Net 核心工作者服务,我 运行 作为 windows 服务。该服务正在使用 appsettings.json 文件作为配置信息。使用 SC CREATE 命令安装服务后,服务失败。

在事件查看器中我发现找不到文件的错误 C:\Windows\System32\appsettings.json。我的服务文件放在不同的文件夹 c:\Services\ 中,而不是查看该位置,服务正在 System32 文件夹中查找文件。

配置注册如下

 var configBuilder = new ConfigurationBuilder()
                   .SetBasePath(Directory.GetCurrentDirectory())
                   .AddJsonFile("appsettings.json");
var configuration = configBuilder.Build();
            services.AddSingleton(configuration);

如何让服务查看本地文件夹?

那是因为当前目录在运行时被更改为 C:\Windows\System32。您可以通过 Assembly.GetExecutingAssembly() 获得相对路径。例如:

var configBuilder = new ConfigurationBuilder()
    .SetBasePath( Path.GetDirectoryName( Assembly.GetExecutingAssembly().Location))
    .AddJsonFile("appsettings.json");
var configuration = configBuilder.Build();

我已成功使用 Host ASP.NET Core in a Windows Service

中的文档

简而言之,您只需在配置生成器步骤中添加 .UseWindowsService(),如下所示:

Host.CreateDefaultBuilder(args)
    .UseWindowsService()
    .ConfigureAppConfiguration((hostContext, configuration) => 
        {
            //...set your configurations here
        })
        .ConfigureServices((hostContext, services) =>
        {
            //...configure you services here
        }

我通过设置 ContentRoot 以不同的方式解决了这个问题。但是我正在使用 Wix 将服务安装到 windows。

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Diagnostics;
using System.IO;

namespace ConverterService
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
            string pathToContentRoot = Path.GetDirectoryName(pathToExe);

            CreateHostBuilder(args, pathToContentRoot).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args, string contentRoot) =>
            Host.CreateDefaultBuilder(args)
                .UseWindowsService()
                .UseContentRoot(contentRoot)
                .ConfigureServices((hostContext, services) =>
                {
                    ConverterConfig config = hostContext.Configuration
                    .GetSection("ConverterConfig")
                    .Get<ConverterConfig>();

                    config.RootPath = contentRoot;

                    services.AddSingleton(config);
                    services.AddHostedService<WindowsBackgroundService>();
                });
    }
}