chadnt
chadnt

Reputation: 1135

Blazor server app hosted in Windows service

How can we host a Blazor server application as a Windows service? Using this article as a guide:

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

We create a minimal example using dotnet version 6.0. First create a blazor server application from template.

dotnet new blazorserver

Then add NuGet package for Microsoft.Extensions.Hosting.WindowsServices

dotnet add package Microsoft.Extensions.Hosting.WindowsServices

In Program.cs, configure the host to run as a Windows service.

//...
builder.Services.AddSingleton<WeatherForecastService>();

// Configure to run as Windows service
builder.Host.UseWindowsService();

var app = builder.Build();
//...

Publish the app as an executable.

dotnet publish -c Release -r win-x64 --self-contained false

Copy contents from /bin/Release/net6.0/win-x64/publish/ folder to server. On the server, cd to the folder with the exe and run the exe from the command line.

PS C:\inetpub\wwwroot\TestBlazor> .\blazor-server-as-service.exe
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: C:\inetpub\wwwroot\TestBlazor\
info: Microsoft.Hosting.Lifetime[0]

Success.

Configure new windows service.

New-service -Name "TestBlazorService" -BinaryPathName C:\inetpub\wwwroot\TestBlazor\blazor-server-as-service.exe

Edit the service to use my credentials. Grant log on as service rights. Start the service.

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

From the event log:

A timeout was reached (30000 milliseconds) while waiting for the TestBlazorService service to connect.

The TestBlazorService service failed to start due to the following error: 
The service did not respond to the start or control request in a timely fashion.

What am I missing?

Upvotes: 1

Views: 3357

Answers (2)

Igor Nedbaylo
Igor Nedbaylo

Reputation: 131

Step 1. Install Microsoft.Extensions.Hosting.WindowsServices from NuGet Package Manager. Step 2. Add to program.cs

using Microsoft.Extensions.Hosting.WindowsServices;

Step 3. Change var builder = WebApplication.CreateBuilder(args); to the following code:

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

Step 4. Add before var app = builder.Build(); to the following code:

builder.Host.UseWindowsService();

Step 5. Publish the app to folder Step 6. Run cmd.exe as administrator. Step 7. Create a Service with the following command:

sc create <SERVICE_NAME> binPath="<BIN_PATH>"

Example:

sc create MySerice binPath="C:\MySolution\MyProject\bin\Release\net7.0\publish\MyProject.exe"

Step 8. Start the Service with the following command:

net start <SERVICE_NAME>

Example:

net start MySerice 

Upvotes: 2

chadnt
chadnt

Reputation: 1135

This took way longer than I'd like to admit. The blazorserver template created a WebApplicationBuilder.

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<IDependencyRepository, DependencyRepository>();

var app = builder.Build();

And I was trying to access and configure the IHostBuilder member, and then build and use the WebBuilder.

//...
builder.Services.AddSingleton<WeatherForecastService>();

// Configure to run as Windows service
builder.Host.UseWindowsService();

var app = builder.Build();

My understanding of the asp.net host model is not great, but I think I need to create an instance of IHostBuilder, configure it to run as a services, and configure the IWebHostBuilder within it for all the web related settings. Then actually build the IHostBuilder - the thing I configured to run as a service.

I added a Startup class to handle the web configuration and changed Program.cs to:

Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>())
    .UseWindowsService()
    .Build()
    .Run();

Installed on server. Service successfully starts and runs. Maybe there's a better way. If not, I hope this will help someone else.

Upvotes: 1

Related Questions