Windows サービス インストーラーを作成する

.NET Windows サービス (.NET Framework Windows サービスとは異なります) を作成するときに、サービスのインストーラーを作成できます。 インストーラーがない場合、ユーザーはサービスをインストールして構成する方法を知る必要があります。 インストーラーは、アプリの実行可能ファイルをバンドルし、カスタマイズ可能なインストール ユーザー エクスペリエンスを公開します。 このチュートリアルは、Windows サービスの作成に関するチュートリアルの続きです。 .NET Windows サービス用のインストーラーを作成する方法を示します。

このチュートリアルで学習する内容は次のとおりです。

  • Visual Studio インストーラー プロジェクト拡張機能をインストールする。
  • セットアップ プロジェクトを作成する。
  • インストールをサポートするように、既存の .NET Worker プロジェクトを更新する。
  • Windows サービス コントロール マネージャーを使用して、インストールとアンインストールを自動化する。

必須コンポーネント

  • Windows サービスの作成に関するチュートリアルを完了しているか、サンプル リポジトリをクローンする準備ができていることが望まれます。
  • .NET 8.0 SDK 以降
  • Windows OS
  • .NET 統合開発環境 (IDE)
  • 既存の .NET 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 セットアップ プロジェクトを追加するには、ソリューション エクスプローラーでソリューションを右クリックして、[追加] > [新しいプロジェクト] を選びます。

Add new project dialog: New MSI Package (Wix v4) Project.

使用できるテンプレートから 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 の [プログラムの追加と削除] 機能を使用してインストーラーを呼び出します。

関連項目