【问题标题】:ASP.Net Core 2.1 application cannot find appsettings.json when ran as a Windows serviceASP.Net Core 2.1 应用程序在作为 Windows 服务运行时找不到 appsettings.json
【发布时间】:2019-11-19 05:36:28
【问题描述】:

我正在尝试在 Windows 10 上将我的 ASP.Net Core 2.1 应用程序作为服务运行。我的应用程序在使用 VS2017 运行时运行良好,或者如果我发布到一个文件夹,然后从该已发布文件夹中使用 --控制台参数。但是,如果我使用 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 所在的已发布文件夹。这让我认为问题在于当前目录在作为服务运行时的设置方式,但我无法准确确定它为什么不工作。

我已按照this Microsoft document 中的说明设置了我的 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 --控制台 应用程序按预期运行。

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

【问题讨论】:

  • 认为在这种情况下您需要将 appsettings.json 放入 bin 文件夹中
  • @JoeAudette,发布文件夹下的 bin 文件夹?在我的情况下是 c:\deployments\casapi\bin?我只是尝试过,它没有任何区别。我认为,如果需要,在 VS2017 中发布到文件夹会这样做。
  • 您可能还必须将 appsettings.json 作为嵌入文件包含在内。

标签: c# asp.net-core .net-core windows-services asp.net-core-2.1


【解决方案1】:

作为App configuration,我们需要调用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();

【讨论】:

    【解决方案2】:

    试试这个。

    Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
    
    【解决方案3】:

    如果你使用的是任务计划程序,你可以将你想要的目录写入

    操作选项卡 --> 编辑 --> 开始于

    因此程序将从该目录开始运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多