Windows Installer手引書 Part.26 アンインストール時にMSIファイル内のダイアログを使用する

[**前の記事へ**](https://qiita.com/tohshima/items/e31e686f52873446497b)　　[**目次へ**](https://qiita.com/tohshima/items/dc4c4721d50a2ad70c7a)　　[**次の記事へ**](https://qiita.com/tohshima/items/f8b0fa5a94189953b050)

## MSI形式インストーラーのアンインストール時のUI

Windowsで一般的にアプリをアンインストールするには、設定の「アプリと機能」、または、コントロールパネルの「プログラムと機能」から行います。このとき表示されるUIは、WiX ToolsetのデフォルトではWindows Installerが標準で持っている簡素なダイアログが使用されます。
![Part26_simpleUninstallDialog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83170/3d9ba3cc-5914-e8df-fb92-3a616d125bf6.png)
また、インストールしたときと同じインストーラーを再度起動すると、
・ようこそ
・インストールの変更、修復、または削除
・[製品名]の削除準備完了
・[製品名]を削除中
・[製品名]セットアップウィザードが完了しました
のようにインストール・ウィザードを辿ってアンインストールを進める形になります。このUIは、MSIファイル内で定義されたダイアログです。
![Part26_RichUninstallDialog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83170/1d60485a-f12b-7d39-cb9a-7447ba99747b.png)
ユーザーはほとんどの場合、インストールしたときのインストーラーを保管していないか、どのファイルを使ったか覚えていないでしょうから、特別な工夫をしないと前者の簡素なダイアログが使われてしまいます。せっかくMSIファイルにアンインストール用のUIを持っているのですから、「アプリと機能」や「プログラムと機能」からアンインストールを開始したときも、MSIファイルで定義したダイアログを表示させるようにしてみましょう。

## インストール時に登録されるレジストリ情報

「アプリと機能」や「プログラムと機能」に表示される項目は、レジストリに登録されています。登録内容に関するマイクロソフトのドキュメントは下記の場所にあります。
**Uninstall Registry Key**
https://docs.microsoft.com/ja-jp/windows/win32/msi/uninstall-registry-key
ここに書かれているように作成される項目は、下記のレジストリキー以下に存在します。

```
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\製品コード
```

MSIからレジストリにアクセスする際にはこのキー名で良いのですが、64bit版Windowsではレジストリエディタで開く場合、下記のキーを指定する必要があります。msiexec.exeは32bitアプリケーションなので、WOW6432Nodeキー以下にリダイレクトされるからです。

```
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\製品コード
```

例えば、このキーの内容は下図のようになっています。
![Part26_UninstallRegkey.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83170/a0034a1f-d10e-87ba-50cf-18e9dd631773.png)
Windows Installerを使ってインストールすると、`WindowsInstaller`という名称の値が作られ`1`が格納されます。これを`0`に変更すれば、MSIファイルに定義したダイアログが表示されるようになります[^1]。

## Uninstallキーの内容を変更する

上記のUninstallキーは[RegisterProductアクション](https://docs.microsoft.com/en-us/windows/win32/msi/registerproduct-action)でレジストリに書き込まれるので、このアクションのあとにレジストリを書き換えるカスタムアクションを挿入します。以下のPropertyエレメントからInstallExecuteSequenceエレメントまでに着目してください。レジストリの内容を書き換えるカスタムアクションはregコマンドを使用し、RegisterProductアクションの後に遅延実行でカスタムアクションを挿入します。

```xml:Product.wxs
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
	<Product Id="85288F48-241D-4227-AFEA-C994D3338332" Name="Part26_02" Language="1041" Version="1.0.0" Manufacturer="tohshima" UpgradeCode="e5bf1c09-caf8-4561-a357-c2ab4d6b962e">
		<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

		<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
		<MediaTemplate />

        <UIRef Id="WixUI_Mondo"/>

        <Property Id="reg_exe" Value="reg"/>
		<CustomAction Id="setWinInstallerReg" Property="reg_exe" 
			ExeCommand="add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\[ProductCode] /v WindowsInstaller /t REG_DWORD /d 0 /f /reg:32" 
			Impersonate="no" Return="asyncNoWait" Execute="deferred"/>
        <InstallExecuteSequence>
            <Custom Action="setWinInstallerReg" After="RegisterProduct">not Installed</Custom>
        </InstallExecuteSequence>

		<Feature Id="ProductFeature" Title="Part26_02" Level="1">
			<ComponentGroupRef Id="ProductComponents" />
		</Feature>
	</Product>

	<Fragment>
		<Directory Id="TARGETDIR" Name="SourceDir">
			<Directory Id="ProgramFilesFolder">
				<Directory Id="INSTALLFOLDER" Name="Part26_02" />
			</Directory>
		</Directory>
	</Fragment>

	<Fragment>
		<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
            <Component Id="cExe" Guid="{5C9ADB2E-63F6-4C26-AF11-2F5A9B0E3015}" >
                <File Id="fExe" Source="C:\Windows\System32\calc.exe" KeyPath="yes"/>
            </Component>
		</ComponentGroup>
	</Fragment>
</Wix>
```

これで、「アプリと機能」や「プログラムと機能」からアンインストールしたときに表示されるダイアログが、MSIファイルに定義したものに変更されます。

[^1]: 残念ながら、マイクロソフトのドキュメントにこの説明はないようです。

[**前の記事へ**](https://qiita.com/tohshima/items/e31e686f52873446497b)　　[**目次へ**](https://qiita.com/tohshima/items/dc4c4721d50a2ad70c7a)　　[**次の記事へ**](https://qiita.com/tohshima/items/f8b0fa5a94189953b050)