0
votes

I have problem loading the correct appsettings.<>.json file when the app is hosted via Windows Service.

Below is the setup for hosting windows service.

https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/windows-service?view=aspnetcore-2.2

 public class Program
    {
        #region ServiceOrConsole

        public static void Main(string[] args)
        {
            var isService = !(Debugger.IsAttached || args.Contains("--console"));
            var builder = CreateWebHostBuilder(args.Where(arg => arg != "--console").ToArray());


            if (isService)
            {
                var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
                var pathToContentRoot = Path.GetDirectoryName(pathToExe);
                //use a path to the app's published location instead of Directory.GetCurrentDirectory().
                builder.UseContentRoot(pathToContentRoot);
            }

            var host = builder.Build();

            if (isService)
            {
                host.RunAsCustomService();
            }
            else
            {             
                host.Run();

            }
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args)
        {
            var cfg = Startup.GetConfiguration();

            return WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()               
                .UseUrls("http://localhost:1234");

        }         
        #endregion
    }

The Get method below should display the correct value of Test depending on the environment. The problem is that it always reads from appsettings.json file.

 [Route("api/[controller]")]
[ApiController]
public class CfgController : ControllerBase
{

    private IConfiguration _configuration;

    public CfgController (IConfiguration configuration)
    {

        _configuration = configuration;
    }


    [HttpGet]
    public IActionResult Get()
    {
        var test =_configuration.GetValue<string>("Test");

        return Ok($"{test}");
    }

}

appsettings.json

    {
  "Test":  "default" 
}

appsettings.Development.json

{
  "Test": "default dev"
}

Below is what I tried, with no avail

1 Passing args to windows service

sc start "My service" --environment "Development"

2 set Windows environment below, and start the service

set ASPNETCORE_ENVIRONMENT=Development
sc start "My service"

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments?view=aspnetcore-2.2 https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/index?view=aspnetcore-2.2#json-configuration-provider https://andrewlock.net/how-to-set-the-hosting-environment-in-asp-net-core/

1

1 Answers

0
votes

Old question, but I ran into the same problem today and had a hard time finding helpful answers. Anyway, my Windows Service seemed to always read from appsettings.json instead of appsettings.Development.json, even though ASPNETCORE_ENVIRONMENT was set to Development.

My research showed me, first of all, that I didn't know anything about Windows Services. Second of all, that the default for a Windows Service is to run under the SYSTEM user (check Task Manager -> Details -> [your service]). This answer was very helpful:

Programs running as SYSTEM (LocalSystem, NT_AUTHORITY\SYSTEM) will have an environment built from the variables specified at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment and at HKEY_USERS.DEFAULT\Environment. Make sure the variables you want it to "see" are defined in one of those locations and they will be accessible.

A simple solution to this is to set ASPNETCORE_ENVIRONMENT as a global environment variable, either using Registry Manager or the command prompt:

setx /M ASPNETCORE_ENVIRONMENT Development

I think it's also possible to run the service as a specific user.