创建 Windows 服务安装程序

创建 .NET Windows 服务时(不会误用 .NET Framework Windows 服务),可能需要为服务创建安装程序。 如果没有安装程序,用户必须知道如何安装和配置服务。 安装程序捆绑应用的可执行文件,并公开可自定义的安装用户体验。 本教程是 “创建 Windows 服务 ”教程的延续。 它演示如何为 .NET Windows 服务创建安装程序。

本教程介绍以下操作:

  • 安装 Visual Studio Installer Projects 扩展。
  • 创建安装项目。
  • 更新现有的 .NET Worker 项目以支持安装。
  • 使用 Windows 服务控制管理器自动安装和卸载。

先决条件

安装工具依赖项

首先安装 Wix 工具集。 Wix 工具集是从 XML 源代码生成 Windows 安装包的一组工具。

dotnet tool install --global wix

接下来,安装 HeatWave for VS2022 扩展。 安装后,重启 Visual Studio,你将看到可用的新项目模板。

获取现有项目

本教程基于使用 BackgroundService 创建 Windows 服务的教程中的应用。 可以克隆示例存储库,也可以使用在上一教程中生成的应用。

小提示

所有“.NET 中的辅助角色”示例源代码都可以在示例浏览器中下载。 有关详细信息,请参阅浏览代码示例:.NET 中的辅助角色

在 Visual Studio 中打开解决方案,然后选择 F5 以确保应用按预期生成并运行。 按 Ctrl+C 停止应用。

添加新安装项目

若要添加新的 Wix 安装项目,请在 解决方案资源管理器 中右键单击解决方案,然后选择“ 添加新 > 项目

“添加新项目”对话框:新建 MSI 包(Wix v4)项目。

从可用模板中选择 MSI 包(Wix v4), 然后选择“ 下一步”。 提供所需的名称和位置,然后选择“创建”。

配置安装程序项目

若要配置安装项目,必须先添加对 App.WindowsService 项目的引用。 右键单击 解决方案资源管理器中的安装项目,然后选择“ 添加 > 项目引用”。

该模板包括示例组件和本地化文件。 删除这些文件,仅保留 Package.wxs 文件。 项目现在应包括一个 ProjectReference 元素,如下所示:

<Project Sdk="WixToolset.Sdk/4.0.0">
  <ItemGroup>
    <ProjectReference Include="..\App.WindowsService.csproj" />
  </ItemGroup>
</Project>

添加项目引用后,配置 Package.wxs 文件。 在编辑器中打开该文件,然后将内容替换为以下内容:

<?xml version="1.0" encoding="UTF-8"?>

<!-- Define the variables in "$(var.*) expressions" -->
<?define Name = ".NET Joke Service" ?>
<?define Manufacturer = "Microsoft" ?>
<?define Version = "1.0.0.0" ?>
<?define UpgradeCode = "9ED3FF33-8718-444E-B44B-69A2344B7E98" ?>

<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
    <Package Name="$(Name)"
             Manufacturer="$(Manufacturer)"
             Version="$(Version)"
             UpgradeCode="$(var.UpgradeCode)"
             Compressed="true">

        <!-- Allow upgrades and prevent downgrades -->
        <MajorUpgrade DowngradeErrorMessage="A later version of [ProductName] is already installed. Setup will now exit." />

        <!-- Define the directory structure -->
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFiles64Folder">

                <!-- Create a folder inside program files -->
                <Directory Id="ROOTDIRECTORY" Name="$(var.Manufacturer)">

                    <!-- Create a folder within the parent folder given the name -->
                    <Directory Id="INSTALLFOLDER" Name="$(Name)" />
                </Directory>
            </Directory>
        </Directory>

        <!-- The files inside this DirectoryRef are linked to
             the App.WindowsService directory via INSTALLFOLDER -->
        <DirectoryRef Id="INSTALLFOLDER">

            <!-- Create a single component which is the App.WindowsService.exe file -->
            <Component Id="ServiceExecutable" Bitness="always64">

                <!-- Copies the App.WindowsService.exe file using the
                     project reference preprocessor variables -->
                <File Id="App.WindowsService.exe"
                      Source="$(var.App.WindowsService.TargetDir)publish\App.WindowsService.exe"
                      KeyPath="true" />

                <!-- Remove all files from the INSTALLFOLDER on uninstall -->
                <RemoveFile Id="ALLFILES" Name="*.*" On="both" />

                <!-- Tell WiX to install the Service -->
                <ServiceInstall Id="ServiceInstaller"
                                Type="ownProcess"
                                Name="App.WindowsService"
                                DisplayName="$(Name)"
                                Description="A joke service that periodically logs nerdy humor."
                                Start="auto"
                                ErrorControl="normal" />

                <!-- Tell WiX to start the Service -->
                <ServiceControl Id="StartService"
                                Start="install"
                                Stop="both"
                                Remove="uninstall"
                                Name="App.WindowsService"
                                Wait="true" />
            </Component>
        </DirectoryRef>

        <!-- Tell WiX to install the files -->
        <Feature Id="Service" Title="App.WindowsService Setup" Level="1">
            <ComponentRef Id="ServiceExecutable" />
        </Feature>

    </Package>
</Wix>

生成项目时,输出是可用于安装和卸载服务的 MSI 文件。

测试安装

若要测试安装程序,请发布 App.WindowsService 项目。 右键单击 解决方案资源管理器中的项目,然后选择“ 发布”。 使用在上一教程中创建的配置文件发布后,可执行文件将位于发布目录中。 接下来, 生成 安装项目并运行安装程序。

需要以管理员身份运行安装。 为此,请右键单击 MSI 文件,然后选择“ 以管理员身份运行”。

安装服务后,可以打开 “服务 ”以查看服务正在运行。 若要卸载该服务,请使用 Windows 添加或删除程序 功能调用安装程序。

另请参阅