ASP.Net Core 2.1 应用程序在作为 Windows 服务运行时找不到 appsettings.json [英] ASP.Net Core 2.1 application cannot find appsettings.json when ran as a Windows service

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

问题描述

我正在尝试在 Windows 10 上将我的 ASP.Net Core 2.1 应用程序作为服务运行.我的应用程序在使用 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:WINDOWSsystem32appsettings.json'.
at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load(Boolean reload)   

我已确认我的 appsettings.json 文件存在于已发布的文件夹中.该错误消息指出正在 C:WINDOWSsystem32 文件夹中查找 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:WINDOWSsystem32 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.

我已按照 此 Microsoft 文档.我的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:deploymentscasapicasapi.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 --控制台应用程序按预期运行.

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

casapi 服务安装为以本地系统帐户登录.

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

推荐答案

As 应用配置,我们需要调用 SetCurrentDirectory 并使用应用发布位置的路径.

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

对于您的问题,您在调用 Directory.SetCurrentDirectory(pathToContentRoot); 之前访问 Directory.GetCurrentDirectory() 调用 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();

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

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆