Windows Installer手引書 Part.14 インストール、アンインストールの区別

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

## カスタムアクションの実行条件

Windows Installer自身には、インストールなのか、アンインストールなのか、アップグレードなのか、といった状況を判断して、アクションを振り分ける機能はありません。インストール用のシーケンスやアンインストール用のシーケンスが、特別に用意されているわけでもありません。そのため、カスタムアクションを組み込む際には、シーケンステーブルのConditionにアクションをいつ実行するのか、条件を記述する必要があります。例えば、[前回](https://qiita.com/tohshima/items/8d1d7e702d58dc1429d2)挙げた例では、下記のようなカスタムアクションをInstallExecuteSequenceに挿入しました。

```xml
<Custom Action="tAct01" After="InstallFiles"></Custom>
```

`Custom`エレメントに囲われた部分がConditionです。何も要素がないので、デフォルトの動作となり、アクションは常に実行されます。前回例に挙げたインストーラーでは、アンインストール時にもアクションが実行されることを観測できます。[ここにConditionに記述できる全ての書式](https://docs.microsoft.com/en-us/windows/win32/msi/conditional-statement-syntax)がまとめられています。多くの場合Conditionにはプロパティが使われますが、そのほかにも多くの機能が利用できます。

## インストール、アンインストール、アップグレード

カスタムアクションのConditionとして最も重要なのが、今インストールしているのかアンインストールしているのか、といった状況判断でしょう。これらの状況は、一般的に標準アクションが設定してくれるプロパティを利用します。[Installation Status Properties](https://docs.microsoft.com/en-us/windows/win32/msi/property-reference#installation-status-properties)や[Feature Installation Options Properties](https://docs.microsoft.com/en-us/windows/win32/msi/property-reference#feature-installation-options-properties)にまとめられているプロパティを使用することになりますが、定型文として使えるように以下にまとめます。なかにはWiX Toolsetでのみ使えるプロパティも含んでいます。

- 新規インストール／メジャーアップグレード  
**NOT Installed**
- 新規インストール（メジャーアップグレードでない時）  
**(NOT Installed) AND (NOT WIX_UPGRADE_DETECTED)**
- メジャーアップグレード（新規インストールでない時）  
**(NOT Installed) AND WIX_UPGRADE_DETECTED**
- マイナーアップグレード／スモールアップグレード／修復  
**REINSTALL**
- マイナーアップグレード／スモールアップグレード（修復でない時）  
**REINSTALL AND (REINSTALL <> "ALL")**[^3]
- コントロールパネルからのアンインストール／インストール物がなくなる変更[^2]／メジャーアップグレードされる側[^1]  
**REMOVE = "ALL"**
- コントロールパネルからのアンインストール／インストール物がなくなる変更[^2]（メジャーアップグレードされる側[^1] でない時）  
**(REMOVE = "ALL") AND (NOT UPGRADINGPRODUCTCODE)**
- メジャーアップグレードされる側[^1] （コントロールパネルからのアンインストール／インストール物がなくなる変更[^2]でない時）  
**UPGRADINGPRODUCTCODE**
- 修復（マイナーアップグレード／スモールアップグレードでない時）  
**REINSTALL = "ALL"**
- インストール物がない変更／インストール物が増える変更  
**Installed AND (NOT REINSTALL) AND (NOT REMOVE)**
- インストール物が減る変更  
**Installed AND (NOT REINSTALL) AND REMOVE AND (REMOVE <> "ALL")**[^3]

以上ではプロパティを論理値として利用していますが、実際には下表の値が入っています。また、`Null`となっているところは、プロパティが存在しないことを示します。

|プロパティ名                  |Installed|REINSTALL    |WIX_UPGRADE_DETECTED  |REMOVE          |UPGRADINGPRODUCTCODE  |
|:-----------------------------|:--------|:------------|:---------------------|:---------------|:---------------------|
|**利用できるタイミング**      |**制限なし**|**制限なし**|**FindRelatedProductsアクションより後**|**InstallValidateアクションより後**|**RemoveExistingProductsアクションより後**|
|新規インストール              |Null     |Null         |Null                  |Null            |Null                  |
|スモールアップグレード        |00:00:00 |Featureのリスト|Null                  |Null            |Null                  |
|マイナーアップグレード        |00:00:00 |Featureのリスト|Null                  |Null            |Null                  |
|メジャーアップグレードする側  |Null     |Null         |メジャーアップグレードされる側の製品コード|Null|Null          |
|メジャーアップグレードされる側|00:00:00 |Null         |Null                  |ALL             |メジャーアップグレードする側の製品コード|
|修復                          |00:00:00 |ALL          |Null                  |Null            |Null                  |
|変更(インストール物に変更がない/増える)|00:00:00|Null       |Null                  |Null            |Null                  |
|変更(インストール物が減る)    |00:00:00 |Null         |Null                  |Featureのリスト   |Null                  |
|変更(インストール物がなくなる)|00:00:00 |Null         |Null                  |ALL             |Null                  |
|削除                          |00:00:00 |Null         |Null                  |ALL             |Null                  |

先の例にあてはめると、新規インストールおよびメジャーアップグレードのときだけカスタムアクションを実行したいときは、下記のように書きます。

```xml
<Custom Action="tAct01" After="InstallFiles">NOT Installed</Custom>
```

[^1]: メジャーアップグレード時には、アップグレードの途中でOSにキャッシュされた旧バージョンのインストーラーがUIなしで起動され、アンインストールが実行されます。「メジャーアップグレードされる側」は、この旧バージョンのインストーラーを指します。
[^2]: 変更インストール時にすべての機能のチェックボックスを外すと、アンインストール処理と同等になります。
[^3]: WiX ToolsetのソースはXMLで記述するので、`<`、`>`等の文字を表現するには、Conditionの文字列を`<![CDATA[`と`]]>`でくくる必要があります。

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