c# - ASP.Net Core 2.1 应用程序在作为 Windows 服务运行时找不到 appsettings.json
问题描述
我正在尝试在 Windows 10 上将我的 ASP.Net Core 2.1 应用程序作为服务运行。我的应用程序在使用 VS2017 运行时运行良好,或者如果我发布到一个文件夹,然后使用 --console arg 从该已发布文件夹中启动它。但是,如果我使用 sc create 创建服务,获得成功结果,然后尝试运行它,我会在 Windows 应用程序日志中收到一条错误消息...
System.IO.FileNotFoundException: The configuration file 'appsettings.json' was not found and is not optional. The physical path is 'C:\WINDOWS\system32\appsettings.json'.
at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load(Boolean reload)
我已确认我的 appsettings.json 文件存在于已发布文件夹中。错误消息指出正在 C:\WINDOWS\system32\ 文件夹中查找 appsettings.json 文件,而不是应用程序 .exe 所在的已发布文件夹。这让我认为问题在于当前目录在作为服务运行时的设置方式,但我无法准确确定它为什么不工作。
我已按照此 Microsoft 文档中的说明设置了我的 Program.cs 。我的 program.cs 如下所示;
public class Program
{
public static IConfiguration Configuration { get; } = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
.AddUserSecrets<Startup>()
.Build();
public static void Main(string[] args)
{
ConfigureSerilog();
// Set up to run as a service if not in Debug mode or if a command line argument is not --console
var isService = !(Debugger.IsAttached || args.Contains("--console"));
if (isService)
{
var processModule = Process.GetCurrentProcess().MainModule;
if (processModule != null)
{
var pathToExe = processModule.FileName;
var pathToContentRoot = Path.GetDirectoryName(pathToExe);
Directory.SetCurrentDirectory(pathToContentRoot);
}
}
var builder = CreateWebHostBuilder(args.Where(arg => arg != "--console").ToArray());
var host = builder.Build();
if (isService)
{
host.RunAsCustomService();
}
else
{
try
{
Log.Information("Starting CAS API in Program.cs");
host.Run();
}
catch (Exception ex)
{
Log.Fatal(ex, "CAS API Host terminated unexpectedly");
}
finally
{
Log.CloseAndFlush();
}
}
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureLogging((hostingContext, logging) => { logging.AddEventSourceLogger(); })
.ConfigureAppConfiguration((context, config) =>
{
// Configure the app here.
})
.UseStartup<Startup>()
.UseSerilog()
.UseUrls("https://localhost:60026"); //This is only used when ran as a stand-alone service. Not in VisualStudio
private static void ConfigureSerilog()
{
// Set up Serilog
var connectionString = Configuration.GetConnectionString("CasDbConnectionString");
const string tableName = "Logs";
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.Filter.ByExcluding(Matching.FromSource("Microsoft.EntityFrameworkCore.Query"))
.Enrich.FromLogContext()
.Enrich.WithMachineName()
.Enrich.WithThreadId()
.Enrich.WithUtcTimeStamp()
.Enrich.WithProperty("Application", $"{System.Reflection.Assembly.GetExecutingAssembly().GetName().Name}")
.Enrich.FromLogContext()
.CreateLogger();
}
我试过更换...
host.RunAsCustomeService();
和 ...
host.RunAsService();
我仍然有同样的问题。
我正在运行 sc 命令,如下所示;
sc create casapi start= auto binPath= c:\deployments\casapi\casapi.exe
我看到了 Windows 服务中列出的 casapi 服务。但是如果我运行 sc 命令...
sc start casapi
我收到上面指出的错误。
如果我在提升的命令提示符中转到已发布的文件夹并键入... casapi.exe --console 应用程序按预期运行。
casapi 服务安装为作为本地系统帐户登录。
解决方案
作为App 配置,我们需要调用 SetCurrentDirectory 并使用指向应用发布位置的路径。
对于您的问题,您可以先访问,然后再Directory.GetCurrentDirectory()
调用。Directory.SetCurrentDirectory(pathToContentRoot);
ConfigureSerilog();
尝试更改顺序
// Set up to run as a service if not in Debug mode or if a command line argument is not --console
var isService = !(Debugger.IsAttached || args.Contains("--console"));
if (isService)
{
var processModule = Process.GetCurrentProcess().MainModule;
if (processModule != null)
{
var pathToExe = processModule.FileName;
var pathToContentRoot = Path.GetDirectoryName(pathToExe);
Directory.SetCurrentDirectory(pathToContentRoot);
}
}
ConfigureSerilog();
推荐阅读
- google-bigquery - 3 个日期之间的日期差异
- java - @ColumnTransformer 未在选择中使用
- sharepoint-2013 - 如何使用 REST 在 SharePoint 2013 设计器中循环访问多值人员字段或查找字段
- google-cloud-platform - 数据集未加载
- identityserver4 - 这是从强命名的 .NET DLL 引用 Thinktecture DLL 的好方法吗?
- ruby - 迭代器这部分的 Ruby 术语是什么?
- python-3.x - 我可以将 scipy.optimize 与 numpy.where 一起使用吗?
- ldap - 冗余负载平衡 LDAP 组的 Freeradius 问题
- c++ - 将 Eigen::MatrixXd(m,n) 与 1x1 矩阵相乘
- java - Appium - 无法访问 hideKeyboard() 方法