Windows Installer手引書 Part.9 プログラムの削除、変更、修復

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

## アプリと機能
Windowsの設定画面を開き、「アプリ」を選択すると「アプリと機能」でインストール済みソフトウェアの削除、変更、修復のほか、インストール済みソフトウェアの情報を見ることができます。Windows7まではコントロールパネルの「プログラムと機能」が使われてきましたが、Windows10でもコントロールパネルから「プログラムと機能」を使うことができます。

WiX Toolsetで作成したインストーラーでは、特別に何もしなくても「アプリと機能」にインストールしたプログラムが登録されます。ここで可能な操作は２通りあります。

- 削除
- 変更

`削除`は文字通りプログラムを削除（アンインストール）します。`変更`はインストーラーで定義したFeatureを一覧表示し、Feature単位でインストールとアンインストールができます。Windows7で使われていたコントロールパネルの「プログラムと機能」からは`修復`を直接呼び出す機能もありましたが、Windows10の設定から呼び出す「アプリと機能」では直接使えなくなりました。`修復`はインストール済みのファイルやレジストリ等が破損していれば修復する機能です。WiX ToolsetでUIを作成した場合は、`変更`を選択すると、インストールウィザードで`修復`機能を呼び出すことができます。

これらの機能はプロパティを定義することで使用するかどうか、切り替えることができます。対応するプロパティは下記の３つです。

|プロパティ|機能|
|:----------|:--|
|ARPNOREMOVE|`削除`を使用しない|
|ARPNOMODIFY|`変更`を使用しない|
|ARPNOREPAIR|`修復`を使用しない|

これらのプロパティを定義すると、特定の機能が使用できなくなります。例えば、WiX Toolsetで「変更」を利用できないようにする場合は、下記のようにプロパティを定義します。

```xml
<Property Id="ARPNOMODIFY" Value="1"/>
```

ここで、`Value`を`1`に指定していますが、`0`を指定しても、また何か別の文字を指定してもプロパティを定義したことになります。`0`のような否定的な値を設定してしまうと、プロパティの機能を無効にしたかのような誤解を受けるので、意図的に`1`のような肯定的な値を指定した方が無難だと思います。

## 「アプリと機能」に表示されるボタンの制御
プロパティを定義することで`削除`や`変更`の機能を無効にすると、「アプリと機能」に表示される[アンインストール]ボタンと[変更]ボタンのEnable状態が変わります。

|ARPNOMODIFY|ARPNOREMOVE|ボタンの状態|
|:----------|:----------|:----------|
|定義なし|定義なし|![TypeA.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83170/5c27079b-94bd-d9c3-0ad0-427879c7d142.png)|
|定義あり|定義なし|![TypeB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83170/cb6991db-4bcb-c663-4e1b-2c3a86d5344d.png)|
|定義なし|定義あり|![TypeC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83170/be65061a-bf41-34a0-0463-31ca163ce876.png)|
|定義あり|定義あり|![TypeC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83170/be65061a-bf41-34a0-0463-31ca163ce876.png)|

`変更`ボタンのみ有効にすることはできません。

## 「アプリと機能」で使えるプロパティ
コントロールパネルの「プログラムと機能」では、[定義済みのプロパティ](https://docs.microsoft.com/en-us/windows/win32/msi/property-reference)のうち`ARP`で始まるものが使えますが、「アプリと機能」では大幅に機能が縮小されて、使えるのは下記のプロパティだけの様です。

- [ARPNOREMOVE](https://docs.microsoft.com/en-us/windows/win32/msi/arpnoremove)
- [ARPNOMODIFY](https://docs.microsoft.com/en-us/windows/win32/msi/arpnomodify)
- [ARPNOREPAIR](https://docs.microsoft.com/en-us/windows/win32/msi/arpnorepair)
- [ARPPRODUCTICON](https://docs.microsoft.com/en-us/windows/win32/msi/arpproducticon)
- [ARPSIZE](https://docs.microsoft.com/en-us/windows/win32/msi/arpsize)
- [ARPSYSTEMCOMPONENT](https://docs.microsoft.com/en-us/windows/win32/msi/arpsystemcomponent)

さきに説明したように`ARPNOREMOVE`プロパティは「アプリと機能」でプログラムを削除することができなくなりますが、「アプリと機能」から製品名が消えることはありません。`ARPSYSTEMCOMPONENT`を使うと、製品名を非表示にすることができます。

## 「アプリと機能」以外から削除、変更、修復する
Wix ToolsetでUI付きのインストーラーを作成した場合、インストール時に使用したインストーラーをもう一度起動すると、デフォルトでは`変更`を選択したときと同様の動作となります。

## レジストリと「アプリと機能」
「アプリと機能」に製品名を表示したり、[アンインストール]ボタンや[変更]ボタンを押したときの機能の呼び出しはWindows Installerの機能ではありません。レジストリに製品名やボタンを押したときに起動するプログラムを登録すると、Windowsシェルが解釈して「アプリと機能」の表示や動作に反映します。Windows Installerの仕事は、インストール時にアンインストールや変更に必要な情報をレジストリ書き出すことです。だから、ルールに沿ってレジストリに項目を作成すれば、自由に製品名を追加することができます。

Windows Installerの仕組みを使ってインストールするだけなら、レジストリに登録される項目を意識する必要はありません。しかし、インストーラーがレジストリにどのような項目を作成するかを知っておけばトラブルシューティングの助けになりますし、「アプリと機能」から特別な処理を呼び出すことができるようになります。

「アプリと機能」に製品を表示するには下記のレジストリキーの下にキーを一つ作り、その下にいくつかの既定の値名でレジストリ項目を作成します。
> HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

例えば私の環境では以下のように項目が並んでいます。
![ex_reg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83170/ec8561c2-5a0c-4c8c-b157-990909e9efe2.png)
これを見ると各製品に対応するキー名はGUIDとアルファベットの製品名と２通りありますが、どちらも「アプリと機能」に表示されます。Windows Installerでインストールすると`ProductCode`プロパティに格納されたGUIDがキー名として使用されます。ここにリストアップされたキーの数に比べて「アプリと機能」に表示されている製品数が圧倒的に少ないのは、`ARPSYSTEMCOMPONENT`の項目を定義して不可視にしているためです。また、64bit版OSでは下記のキーも同様に使用されます。「アプリと機能」には上記のレジストリ以下の製品名と区別なく表示されるため、「アプリと機能」を見ただけではどちらのレジストリに製品が登録されているか区別することはできません。
> HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall

## よく使われるレジストリ項目
私がよく使う（もしくはよく確認する）レジストリ項目を挙げておきます。

|レジストリ名称|MSIのプロパティ名|WiX Toolsetソースの定義場所|使われ方と意味|
|:------------|:---------------|:------------------------|:--|
|DisplayName|ProductName|ProductエレメントのName属性。|「アプリと機能」の表示に使用される製品名。|
|DisplayVersion|ProductVersion |ProductエレメントのVersion属性。|「アプリと機能」で製品名をクリックすると表示されるバージョン番号。|
|EstimatedSize|なし。Featureの選択によって変化するため、インストール実行時に決まる。|なし。|「アプリと機能」の製品名右側に表示される、インストールで使用したディスク容量。|
|UninstallString|直接対応するものはなし。ProductCodeプロパティからWindows Installerが自動生成する。|なし。|「アプリと機能」の[アンインストール]ボタンを押すと、コマンドとして実行される。|
|InstallSource|対応するものはなし。インストール実行時、Windows Installerが自動生成する。|なし。|インストールで使用した、.MSIファイルを置いたディレクトリへのパス。|

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