web-dev-qa-db-fra.com

ASP.NET CORE 2.1 L'application ne peut pas trouver appsettings.json lors de son service Windows

J'essaie d'exécuter mon application ASP.NET CORE 2.1 en tant que service sur Windows 10. Mon application s'exécute bien lors de l'utilisation de VS2017 ou si je publie dans un dossier, puis de la démarrer dans ce dossier publié avec le --Console Arg. Cependant, si j'utilise SC Créer pour créer le service, obtenez un résultat de réussir, puis essayez de l'exécuter, je reçois une erreur dans le journal des applications Windows indiquant ...

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)   

J'ai confirmé que mon fichier appsettings.json existe dans le dossier publié. Le message d'erreur indique que c'est la recherche dans le dossier C:\Windows\System32\pour le fichier appsetTes.json plutôt que le dossier publié dans lequel l'application .exe réside. Cela me conduit à penser que le problème est avec la manière dont le répertoire actuel est défini lors de son service, mais j'ai du mal à identifier exactement pourquoi cela ne fonctionne pas.

J'ai mis en place mon programme.cs en suivant les instructions dans ce document Microsoft . Mon programme est présenté ci-dessous;

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

    }

J'ai essayé de remplacer le ...

Host.RunAsCustomeService();

avec ...

Host.RunAsService();

Et j'ai toujours eu le même problème.

Je gère la commande sc comme suit;

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

Et je vois le service Casapi répertorié dans Windows Services. Mais si je gère la commande sc ...

sc start casapi 

Je reçois l'erreur indiquée ci-dessus.

Si je vais au dossier publié dans une invite de commande élevée et que vous tapez ... CASAPI.EXE --Console L'application fonctionne comme prévu.

Le service CASAPI est installé pour se connecter en tant que compte système local.

7
whiskytangofoxtrot

Essaye ça.

Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
3
Vlad