'ASP.NET Core (.Net 6) Web Application throws System.NotSupportedException when run as a service. (Service will not start)

When I attempt to run my .Net Web Application as a Windows Service, it does not start. It works if I just run the executable but mysteriously fails when attempting to run as a service. I have logged the relevant error messages and reported my solution below.

The following exception is in the event viewer.

Exception in Event Viewer

Application: WebApplication5.exe CoreCLR Version: 6.0.222.6406 .NET Version: 6.0.2 Description: The process was terminated due to an unhandled exception. Exception Info: System.NotSupportedException: The content root changed from "C:\Windows\system32" to "C:\Program Files (x86)\My Company\webapp5". Changing the host configuration using WebApplicationBuilder.Host is not supported. Use WebApplication.CreateBuilder(WebApplicationOptions) instead. at Microsoft.AspNetCore.Builder.ConfigureHostBuilder.ConfigureHostConfiguration(Action1 configureDelegate) at Microsoft.Extensions.Hosting.HostingHostBuilderExtensions.UseContentRoot(IHostBuilder hostBuilder, String contentRoot) at Microsoft.Extensions.Hosting.WindowsServiceLifetimeHostBuilderExtensions.UseWindowsService(IHostBuilder hostBuilder, Action1 configure) at Microsoft.Extensions.Hosting.WindowsServiceLifetimeHostBuilderExtensions.UseWindowsService(IHostBuilder hostBuilder) at Program.$(String[] args) in C:\Users\Jonathan\source\repos\WebApplication5\WebApplication5\Program.cs:line 10

Steps to Recreate

Program.cs

My application is based on the ASP.NET Core Web API template. I followed instructions on https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/windows-service?view=aspnetcore-6.0&tabs=visual-studio#app-configuration and added UseWindowsService() to Program.cs

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Host.UseWindowsService();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Deploy binary and create a service

I compile a binary with dotnet publish -c Debug --self-contained --runtime win-x64 -p:PublishSingleFile=true

Copy the output to the target machine and run in an Administrative Powershell

New-Service -Name WebApplication5 -BinaryPathName C:\Users\WDAGUtilityAccount\Desktop\webapp5\WebApplication5.exe

When I attempt to start the service:

    PS C:> Start-Service WebApp5
    Start-Service : Service 'WebApp5 (WebApp5)' cannot be started due to the following error: Cannot start service WebApp5 on computer '.'.
    At line:1 char:1
    + Start-Service WebApp5
    + ~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : OpenError: (System.ServiceProcess.ServiceController:ServiceController) [Start-Service], ServiceCommandException
        + FullyQualifiedErrorId : CouldNotStartService,Microsoft.PowerShell.Commands.StartServiceCommand

When I use the Services GUI:

Windows could not start the WebApplication5 service on Local Computer

Error 1053:The service did not respond to the start or control request in a timely fashion.



Solution 1:[1]

Like the exception in event-viewer suggests, I needed to use a non-default constructor in Program.cs and set the ContentRootPath there.

Changing program.cs fixed this issue.

//set ContentRootPath so that builder.Host.UseWindowsService() doesn't crash when running as a service
var webApplicationOptions = new WebApplicationOptions
{
    ContentRootPath = AppContext.BaseDirectory,
    Args = args,
};    
var builder = WebApplication.CreateBuilder(webApplicationOptions);

//All the following code is unchanged from my original program.cs

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Host.UseWindowsService();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Solution 2:[2]

Works like a charm! Thanks.

one more line added to setup the url:

builder.WebHost.UseUrls("http://localhost:" + _portNo);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jon
Solution 2 nickong