Host ASP (.NET 6) in a Windows Service

Viewed 8255

I am currently hosting an ASP.NET (.NET 5) application in a Windows Service using WebHost and WebHostBuilder.

.NET 6 introduced WebApplication and WebApplicationBuilder. How can I use these to host in a Windows Service?

2 Answers

You would use the UseWindowsService() extension method documented here:

https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/windows-service?view=aspnetcore-6.0&tabs=visual-studio#app-configuration

As is the case in previous versions, you need to install the Microsoft.Extensions.Hosting.WindowsServices NuGet package.

Implementing this in .NET 6 with WebApplicationBuilder requires a workaround:

var webApplicationOptions = new WebApplicationOptions() { ContentRootPath = AppContext.BaseDirectory, Args = args, ApplicationName = System.Diagnostics.Process.GetCurrentProcess().ProcessName };
var builder = WebApplication.CreateBuilder(webApplicationOptions);

builder.Host.UseWindowsService();

Updated:

Microsoft has changed how services should be created as the fix for this. The --contentRoot argument should be used with the exe.

sc config MyWebAppServiceTest binPath= "$pwd\WebApplication560.exe --contentRoot $pwd\"
New-Service -Name {SERVICE NAME} -BinaryPathName "{EXE FILE PATH} --contentRoot {EXE FOLDER PATH}" -Credential "{DOMAIN OR COMPUTER NAME\USER}" -Description "{DESCRIPTION}" -DisplayName "{DISPLAY NAME}" -StartupType Automatic

I had an existing console app that was only running an Microsoft.Extensions.Hosting.IHostedService implementation targeting .Net 6 and wanted to add a web interface that would be available when the service was running. I think this is what you're doing.

Steps

  1. Switching the Sdk attribute on the root node of the project file enter image description here
  2. Reload the project
  3. Updated the code in Program.cs

New Program Class

using MyWindowsService.App;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

// Create the builder from the WebApplication but don't call built yet
var appBuilder = WebApplication.CreateBuilder(args);

// Add the windows service class as a HostedService to the service collection on the builder
appBuilder.Services.AddHostedService<MyWindowsService>();

// Build the builder to get a web application we can map endpoints to
var app = appBuilder.Build();

// Map an endpoint
app.MapGet("/", () => "Hello World!");

// Run the web application 
app.Run();

Old Program Class

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace MyWindowsService.App
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args)
        {
            return Host.CreateDefaultBuilder(args)
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddHostedService<MyWindowsService>();
                });
        }
    }
}
Related