skip to Main Content

I have an API build with .NET 6 that I would like to host as a Windows Service. For that, I followed the official docs and added the below code to my Program.cs:

var options = new WebApplicationOptions
{
    Args = args,
    ContentRootPath = WindowsServiceHelpers.IsWindowsService() ? AppContext.BaseDirectory : default
};

var builder = WebApplication.CreateBuilder(options);


builder.Host.UseWindowsService(options =>
{
    options.ServiceName = "Service Name";
});

Now I want to build this app into a single executable, self-contained, for that, I run the following command:

dotnet publish -r win-x64 /p:PublishSingleFile=true /p:IncludeNativeLibrariesForSelfExtract=true /p:IncludeAllContentForSelfExtract=true --self-contained true

That works all fine. Now to create and run a service I’m using the below:

New-Service -Name $serviceName -BinaryPathName "$exePath --contentRoot $contentRootPath" -DisplayName $displayName -Description $description -StartupType $startupType

Unfortunately, that doesn’t change the content root path and appsettings.json is not read. When I try to run the service, the content root path is still set to C:WINDOWSTEMP.netmonitor.APIot3bwp1B__+k8mUZcxQc6zWIACPmScw=

Any idea how can I set the content root path so it’s poinitng to the folder with executable?

2

Answers


  1. Chosen as BEST ANSWER

    I'm not sure if this is the correct approach, but I was able to fix it by providing an additional appsettings.json file by doing this:

    string processDirectory = Path.GetDirectoryName(Environment.ProcessPath);
    
    if (WindowsServiceHelpers.IsWindowsService())
    {
        Log.Information("Adding new json config");
        builder.Configuration.AddJsonFile(Path.Combine(processDirectory, "appsettings.json"), optional: false, reloadOnChange: true);
    
        Log.Information("app settings json: {0}", Path.Combine(processDirectory, "appsettings.json"));
    }
    

    This solved the problem for me, and the appsettings in now read from an additional location.

    I had to do the same for each location that was pointing to ContentRootPath like my sqlLite db file location as well.


  2. I think the AppContext.BaseDirectory is used for assembly resolution.

    Try using System.Environment.CurrentDirectory instead.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search