14

I created a new ASP.NET Core project with Visual Studio 2022 Preview and I am trying to run it as a Windows Service. I downloaded the latest Microsoft.Extensions.Hosting.WindowsServices package (6.0.0-preview.7.21377.19).

When researching online the function .UseWindowsService() goes into CreateHostBuilder method. But in the new template it looks different. I cannot understand where I should call .UseWindowsService in the new template. This is my current code, it looks like the service is starting but then when I browse to localhost:5000 it gives me 404 error

using Microsoft.OpenApi.Models;
using Microsoft.Extensions.Hosting.WindowsServices;

var builder = WebApplication.CreateBuilder(args);

builder.Host.UseWindowsService(); // <--- Added this line

// Add services to the container.

builder.Services.AddControllers();
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new() { Title = "MyWindowsService", Version = "v1" });
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (builder.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
        app.UseSwagger();
    app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "MyWindowsService v1"));
}

app.UseAuthorization();

app.MapControllers();


app.Run();

I published my service exe like this

dotnet publish -c Release -r win-x64 --self-contained
cvalueapp
  • 179
  • 1
  • 1
  • 4
  • Can you access `http://localhost:5000/swagger/v1/swagger.json` ? – Jason Pan Sep 10 '21 at 09:53
  • No and it seems like the service didn't start either. "The MyService service failed to start due to the following error: The service did not respond to the start or control request in a timely fashion." – cvalueapp Sep 10 '21 at 11:00
  • The error seems to be this:CoreCLR Version: 6.0.21.45113 .NET Version: 6.0.0-rc.1.21451.13 Description: The process was terminated due to an unhandled exception. Exception Info: System.NotSupportedException: The content root changed. Changing the host configuration is not supported at Microsoft.AspNetCore.Builder.ConfigureHostBuilder.ConfigureHostConfiguration(Action`1 configureDelegate) at Microsoft.Extensions.Hosting.HostingHostBuilderExtensions.UseContentRoot(IHostBuilder hostBuilder, String contentRoot) – cvalueapp Sep 10 '21 at 11:04
  • How do you create this project? If you want to host the ASP.NET Core in a Windows Service, you can refer to [this document](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/windows-service?view=aspnetcore-6.0&tabs=netcore-cli#create-and-manage-the-windows-service) – Fei Xue Sep 22 '21 at 07:16
  • @cvalueapp Did you ever find a solution to this? – user3071284 Oct 11 '21 at 20:09

2 Answers2

28

Since simply using

builder.Host.UseWindowsService();

will not work with WebApplication.CreateBuilder() (see), but instead will throw the exception

Exception Info: System.NotSupportedException: The content root changed from "C:\Windows\system32\" to "...". Changing the host configuration using WebApplicationBuilder.Host is not supported. Use WebApplication.CreateBuilder(WebApplicationOptions) instead.

or rather will cause this error

Start-Service : Service 'Service1 (Service1)' cannot be started due to the following error: Cannot start service Service1 on computer '.'.

when trying to start the Service with Start-Service in PowerShell, I found a workaround that worked for me

using Microsoft.Extensions.Hosting.WindowsServices;

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

var builder = WebApplication.CreateBuilder(options);

builder.Host.UseWindowsService();

here: An asp.net core web api application, using "UseWindowsService", reports an error “System.NotSupportedException: The content root changed. Changing the host configuration is not supported ” when starting the service

Michael Goll
  • 381
  • 3
  • 5
  • 1
    This solved the issue for me. I had the exact same problem as is in the question. And as cvalueapp explained in the comments, starting the service failed because of an exception caused by the change of the content root. This answer shows how to work around this issue. – sbecker Mar 13 '22 at 19:01
3

The following coding sets the lifetime to WindowsServiceLifetime and enables logging to the event log. In most cases this should be all you need to run the app as a Windows Service.

if (WindowsServiceHelpers.IsWindowsService())
{
    appBuilder.Services.AddSingleton<IHostLifetime, WindowsServiceLifetime>();
    appBuilder.Logging.AddEventLog(settings =>
    {
        if (string.IsNullOrEmpty(settings.SourceName))
        {
            settings.SourceName = appBuilder.Environment.ApplicationName;
        }
    });
}
Thomas Erdösi
  • 534
  • 3
  • 15
  • This didn't work for me because it does not configure the content root path. The code is just a subset of what UseWindowsServices does. – candritzky Mar 09 '22 at 12:23
  • @candritzky: You can set the content root path when calling the constructor of the WebApplicationBuilder. – Thomas Erdösi Mar 10 '22 at 17:58
  • 1
    @ThomasErdösi, when stating something can be done that is not shown in your example, please provide a code sample. – James Jensen May 23 '22 at 12:52