我有一个 .Net core 辅助服务,我将其作为 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();
我已成功使用 在 Windows 服务中托管 ASP.NET Core
中的文档简而言之,您应该在配置构建器步骤中添加
.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>();
});
}
}
我发现
Assembly.GetExecutingAssembly().Location
(如其他答案中所建议的那样)从 .Net 8 Windows 服务调用时返回空字符串。 AppContext.BaseDirectory
对我有用:
.SetBasePath(AppContext.BaseDirectory)