7.8 KiB
title | author | description | manager | ms.author | ms.custom | ms.date | ms.prod | ms.technology | ms.topic | uid |
---|---|---|---|---|---|---|---|---|---|---|
Host ASP.NET Core in a Windows Service | guardrex | Learn how to host an ASP.NET Core app in a Windows Service. | wpickett | tdykstra | mvc | 06/04/2018 | aspnet-core | aspnet | article | host-and-deploy/windows-service |
Host ASP.NET Core in a Windows Service
By Luke Latham and Tom Dykstra
An ASP.NET Core app can be hosted on Windows without using IIS as a Windows Service. When hosted as a Windows Service, the app can automatically start after reboots and crashes without requiring human intervention.
View or download sample code (how to download)
Get started
The following minimum changes are required to set up an existing ASP.NET Core project to run in a service:
-
In the project file:
- Confirm the presence of the runtime identifier or add it to the <PropertyGroup> that contains the target framework:
<PropertyGroup> <TargetFramework>netcoreapp2.1</TargetFramework> <RuntimeIdentifier>win7-x64</RuntimeIdentifier> </PropertyGroup>
- Add a package reference for Microsoft.AspNetCore.Hosting.WindowsServices.
- Confirm the presence of the runtime identifier or add it to the <PropertyGroup> that contains the target framework:
-
Make the following changes in
Program.Main
:-
Call host.RunAsService instead of
host.Run
. -
If the code calls
UseContentRoot
, use a path to the app's published location instead ofDirectory.GetCurrentDirectory()
.::: moniker range=">= aspnetcore-2.0"
::: moniker-end
::: moniker range="< aspnetcore-2.0"
::: moniker-end
-
-
Publish the app to a folder. Use dotnet publish or a Visual Studio publish profile that publishes to a folder.
To publish the sample app from the command line, run the following command in a console window from the project folder:
dotnet publish --configuration Release --output c:\svc
-
Use the sc.exe command-line tool to create the service (
sc create <SERVICE_NAME> binPath= "<PATH_TO_SERVICE_EXECUTABLE>"
). ThebinPath
value is the path to the app's executable, which includes the executable file name. The space between the equal sign and the quote character that starts the path is required.For the sample app and command that follows, the service is:
- Named MyService.
- Published to c:\svc folder.
- Has an app executable named AspNetCoreService.exe.
Open a command shell with administrative privileges and run the following command:
sc create MyService binPath= "c:\svc\aspnetcoreservice.exe"
Make sure the space is present between the
binPath=
argument and its value. -
Start the service with the
sc start <SERVICE_NAME>
command.To start the sample app service, use the following command:
sc start MyService
The command takes a few seconds to start the service.
-
The
sc query <SERVICE_NAME>
command can be used to check the status of the service to determine its status:START_PENDING
RUNNING
STOP_PENDING
STOPPED
Use the following command to check the status of the sample app service:
sc query MyService
-
When the service is in the
RUNNING
state and if the service is a web app, browse the app at its path (by default,http://localhost:5000
, which redirects tohttps://localhost:5001
when using HTTPS Redirection Middleware).For the sample app service, browse the app at
http://localhost:5000
. -
Stop the service with the
sc stop <SERVICE_NAME>
command.The following command stops the sample app service:
sc stop MyService
-
After a short delay to stop a service, uninstall the service with the
sc delete <SERVICE_NAME>
command.Check the status of the sample app service:
sc query MyService
When the sample app service is in the
STOPPED
state, use the following command to uninstall the sample app service:sc delete MyService
Provide a way to run outside of a service
It's easier to test and debug when running outside of a service, so it's customary to add code that calls RunAsService
only under certain conditions. For example, the app can run as a console app with a --console
command-line argument or if the debugger is attached:
::: moniker range=">= aspnetcore-2.0"
Because ASP.NET Core configuration requires name-value pairs for command-line arguments, the --console
switch is removed before the arguments are passed to CreateDefaultBuilder.
::: moniker-end
::: moniker range="< aspnetcore-2.0"
::: moniker-end
Handle stopping and starting events
To handle OnStarting, OnStarted, and OnStopping events, make the following additional changes:
-
Create a class that derives from WebHostService:
-
Create an extension method for IWebHost that passes the custom
WebHostService
to ServiceBase.Run: -
In
Program.Main
, call the new extension method,RunAsCustomService
, instead of RunAsService:::: moniker range=">= aspnetcore-2.0"
::: moniker-end
::: moniker range="< aspnetcore-2.0"
::: moniker-end
If the custom WebHostService
code requires a service from dependency injection (such as a logger), obtain it from the IWebHost.Services property:
Proxy server and load balancer scenarios
Services that interact with requests from the Internet or a corporate network and are behind a proxy or load balancer might require additional configuration. For more information, see Configure ASP.NET Core to work with proxy servers and load balancers.
Kestrel endpoint configuration
For information on Kestrel endpoint configuration, including HTTPS configuration and SNI support, see Kestrel endpoint configuration.