Create a Windows Service installer
When you create a .NET Windows Service (not to be mistaken with a .NET Framework Windows Service), you may want to create an installer for your service. Without an installer, users would have to know how to install and configure your service. An installer bundles your app's executables and exposes a customizable installation user experience.
In this tutorial, you'll learn how to:
- Install the Visual Studio Installer Projects extension.
- Create a setup project.
- Update an existing .NET Worker project to support installation.
- Automate the installation and uninstallation with the Windows Service Control Manager.
Prerequisites
- The .NET 6.0 SDK or later
- A Windows OS
- A .NET integrated development environment (IDE)
- Feel free to use Visual Studio
- An existing .NET Windows Service
Install the extension
Install the Microsoft Visual Studio Installer Projects extension. After installing, restart Visual Studio and you'll see new project templates available.
Update existing project
This tutorial is based on the app created as part of the Create a Windows Service using BackgroundService
tutorial. You can either clone the sample repo or use the app you built in the previous tutorial.
Tip
All of the "Workers in .NET" example source code is available in the Samples Browser for download. For more information, see Browse code samples: Workers in .NET.
Open the solution in Visual Studio, and select F5 to ensure that the app builds and runs as expected. Press Ctrl+C to stop the app.
Handle installation switches
The Windows Service app needs to handle installation switches. The setup project will call into the Windows Service app with /Install
and /Uninstall
switches during installation and uninstallation respectively. When these switches are present, the app will behave differently, in that it will only perform installation or uninstallation using the Windows Service Control Manager executable (sc.exe).
For the app to call a separate process, install the CliWrap NuGet package as a convenience. To install the CliWrap
package, use the dotnet add package
command:
dotnet add App.WindowsService.csproj package CliWrap
For more information, see dotnet add package.
With CliWrap
installed, open the Program.cs file of the App.WindowsService
project. After the using
statements, but before the IHost
is created, add the following code:
using CliWrap;
const string ServiceName = ".NET Joke Service";
if (args is { Length: 1 })
{
string executablePath =
Path.Combine(AppContext.BaseDirectory, "App.WindowsService.exe");
if (args[0] is "/Install")
{
await Cli.Wrap("sc")
.WithArguments(new[] { "create", ServiceName, $"binPath={executablePath}", "start=auto" })
.ExecuteAsync();
}
else if (args[0] is "/Uninstall")
{
await Cli.Wrap("sc")
.WithArguments(new[] { "stop", ServiceName })
.ExecuteAsync();
await Cli.Wrap("sc")
.WithArguments(new[] { "delete", ServiceName })
.ExecuteAsync();
}
return;
}
The preceding code:
- Declares the service name as a
const string
value. - Checks the
args
for a single value. - Gets the executable path from the AppContext.BaseDirectory.
- When the
"/Install"
switch is present,sc create ".NET Joke Service" binPath="path/to/App.WindowsService.exe" start=auto
is called. - When the
"/Uninstall"
switch is present,sc stop ".NET Joke Service"
andsc delete ".NET Joke Service"
are called.
When no installation switches are present, the app behaves as it did before, but it now includes installation functionality.
Add new setup project
To add a new setup project, right-click on the solution in the Solution Explorer and select Add > New Project:
Select Setup Project from the available templates, then select Next. Provide the desired Name and Location, then select Create.
Configure installer project
To configure the install project, select the project in the Solution Explorer. Select F4 to open the project properties pane. You can configure the app's "add" and "remove" icons, author, manufacturer, product name, title, target platform, and so on.
The installer project needs to define two custom actions for installation behavior. Right-click the project in the Solution Explorer, and then select View > Custom Actions.
From the Custom Actions window, select Install > Add Custom Action.
Double-click the Application Folder, and select Publish Items from App.WindowsService (Active).
Select Ok to confirm the selection. Right-click the added Publish Items from App.WindowsService (Active) node under Install, then select Properties.
Add /Install
to the Arguments. Follow these same steps for Uninstall, adding /Uninstall
to the Arguments.
Once you've done both, you should see the following:
With these updates, the setup project has been configured to delegate its Install and Uninstall actions to call into the Windows Service app with appropriate arguments.
Test installation
To test the installer, expand Solution Configurations in Visual Studio, and select Release (assuming Debug was selected). Build the solution and then right-click on the setup project and select Build. By default, setup projects are not part of the build.
Select View > Output, and ensure that the Show output from dropdown has Build selected. The Microsoft Installer (MSI) file path is displayed. Copy the path, and open the installer. Run the installer:
Once the service is installed, you can open Services to start the service. To uninstall the service, use the Windows Add or Remove Programs feature to call the installer.
See also
Feedback
Submit and view feedback for