本文介绍了作为Windows服务运行时,ASP.Net Core 2.1应用程序找不到appsettings.json的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将ASP.Net Core 2.1应用程序作为服务在Windows 10上运行。使用VS2017运行时,或者如果我发布到某个文件夹,然后使用-从该发布的文件夹中启动它,则我的应用程序运行良好。控制台参数但是,如果我使用sc create创建服务,获得成功结果,然后尝试运行它,则Windows应用程序日志中将显示错误消息,指出...

I am trying to run my ASP.Net Core 2.1 application as a service on Windows 10. My application runs fine when ran using VS2017 or if I publish to a folder and then start it from within that published folder with the --console arg. However, if I use sc create to create the service, getting a Success result, and then try to run it, I get an error in the Windows Application log stating...

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所在的已发布文件夹。这使我认为问题出在作为服务运行时设置当前目录的方式,但是我很难确定它为什么不起作用。

I have confirmed that my appsettings.json file exists in the published folder.The error message states that is is looking in the C:\WINDOWS\system32\ folder for the appsettings.json file rather than the published folder where the application .exe resides. This leads me to think the issue is with the way the current directory is being set when ran as a service, but I am having trouble identifying exactly why it is not working.

我已经按照。我的program.cs如下所示;

I have set up my Program.cs by following the instructions in this Microsoft document. My program.cs is shown below;

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();

我仍然遇到相同的问题。

And I still had the same problem.

我正在按以下方式运行sc命令;

I am running the sc command as follows;

sc create casapi start= auto binPath= c:\deployments\casapi\casapi.exe

我看到Windows服务中列出了casapi服务。但是,如果我运行sc命令...

And I see the casapi service listed in Windows Services. But if I run the sc command...

sc start casapi

我得到上面指出的错误。

I get the error indicated above.

如果我在提升权限的命令提示符下进入已发布的文件夹,然后键入...
casapi.exe --console
该应用程序的运行方式为

If I go to the published folder in an elevated command prompt and type... casapi.exe --consoleThe application runs as expected.

casapi服务已安装为作为本地系统帐户登录。

The casapi service is installed to Log On as a local system account.

推荐答案

为,我们需要调用SetCurrentDirectory并使用指向该应用发布位置的路径。

As App configuration, we need to call SetCurrentDirectory and use a path to the app's published location.

对于您的问题,在调用 Directory.SetCurrentDirectory之前,请访问 Directory.GetCurrentDirectory() (pathToContentRoot); 首先调用 ConfigureSerilog();

For your issue, you access Directory.GetCurrentDirectory() before calling Directory.SetCurrentDirectory(pathToContentRoot); as you call ConfigureSerilog(); first.

尝试更改顺序,例如

    // 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();

这篇关于作为Windows服务运行时,ASP.Net Core 2.1应用程序找不到appsettings.json的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-06 02:39