Windows Installer手引書 Part.4 Feature

[**前の記事へ**](https://qiita.com/tohshima/items/44fa86262e40ec2751a2)　　[**目次へ**](https://qiita.com/tohshima/items/dc4c4721d50a2ad70c7a)　　[**次の記事へ**](https://qiita.com/tohshima/items/9c992f16d08f9b3b962d)

# Feature
## 基本的なFeatureの使い方

これまで、Component、Directoryを説明してきましたが、Featureを定義すればファイルやレジストリをインストールできます。基本は、Featureエレメントの子エレメントとしてインストールしたいComponentのIdを持つComponentRefエレメントを置くことです。例えば、IdがexeComponent、pngComponentのComponentをインストールしたければ次のようになります。

```xml
 1: <Feature Id="ProductFeature" Title="Part4_01" Level="1">
 2:   <ComponentRef Id="exeComponent" />
 3:   <ComponentRef Id="pngComponent" />
 4: </Feature>
```

しかし、このやり方だとComponentが増えるたびにFeatureエレメントの子エレメントとしてComponentRefエレメントを追加しなければなりません。そこで、インストールしたい全てのComponentエレメントをComponentGroupエレメントでくくってしまえば、Componentを追加してもFeatureエレメントの子エレメントを変更する必要がなくなります。例えば、Componentを下記のように定義します。

```xml
 1: <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
 2:   <Component Id="exeComponent" Guid="e198536a-2730-4dd7-97e2-b8d5b3466497">
 3:     <File Id="calcFile" KeyPath="yes" Source="C:\Windows\System32\calc.exe" />
 4:   </Component>
 5:   <Component Id="pngComponent" Guid="ea36035e-7ddd-4f3d-9995-1c64adb5ffae">
 6:     <File Id="pngFile" KeyPath="yes" Source="C:\Windows\System32\SecurityAndMaintenance.png" />
 7:   </Component>
 8: </ComponentGroup>
```

そうすると、Featureエレメントの子エレメントは下記のように簡略化できます。

```xml
 1: <Feature Id="ProductFeature" Title="Part4_01" Level="1">
 2:   <ComponentGroupRef Id="ProductComponents" />
 3: </Feature>
```

これならComponentGroupエレメントの子にComponentエレメントを追加していけばFeatureエレメントに変更を加える必要がありません。WiX ToolsetがVisual Studioにインストールする「新しいプロジェクト」のテンプレートもこの構造になっていて、シンプルなインストーラーならFeatureエレメントに変更を加える必要がないようになっています。

## ユーザーが機能を選択できるようにする

大規模なアプリではインストールウィザード内でインストールしたい機能を選択できるようにしたものがあります。Featureはユーザーが機能を選択したとき、どのComponentをインストールするか定義するためにあります。WiXでUI付きのインストーラーを作成するなら、CustomizeDlgを表示するだけでFeatureエレメントの定義通りに機能が選択可能になります。例えば、下記のようにFeatureを定義します。

```xml
 1: <Feature Id="writeFeature" Title="Write" Level="1">
 2:   <ComponentGroupRef Id="writeComponents" />
 3: </Feature>
 4: <Feature Id="calcFeature" Title="Calc" Level="1">
 5:   <ComponentGroupRef Id="calcComponents" />
 6: </Feature>
 7: <Feature Id="paintFeature" Title="Paint" Level="1">
 8:   <ComponentGroupRef Id="paintComponents" />
 9: </Feature>
```

こうすると、CustomizeDlgは下図のような表示になります。
![Part4Fig01.png](https://qiita-image-store.s3.amazonaws.com/0/83170/97408b26-8719-74e3-34a0-b130e75501e4.png)
Featureエレメントにはこの画面の選択肢を制御する色々な機能があるので、WiXのドキュメント[Feature Element](http://wixtoolset.org/documentation/manual/v3/xsd/wix/feature.html)を参照してください。

## INSTALLLEVELとFeature

FeatureエレメントのLevel属性にはInstall Levelを0以上の数値で指定します。0を設定したFeatureはインストールされません。INSTALLLEVELプロパティに設定された数値以下（等しい数値も含む）のInstall Levelを持つFeatureがインストールされます。INSTALLLEVELに何も設定しなかった場合は1が入っています。最も簡単にInstall Levelを利用する方法は、SetupTypeDlgを利用することです。
![Part4Fig02.png](https://qiita-image-store.s3.amazonaws.com/0/83170/23c188a1-034d-0663-a001-1616a4f2aa37.png)
[Typical]ボタンはINSTALLLEVELを3に、[Complete]ボタンはINSTALLLEVELを1000に設定します[^1]。これに合わせてFeatureエレメントのLevel属性を設定すれば、望みの動作になります。[Custom]ボタンはCustomizeDlgを表示し、INSTALLLEVELにとらわれずに機能を選択するとき利用します。INSTALLLEVELはPublic Propertyなので[^2]msiexecのコマンドラインから指定することもできます。SetupTypeDlgを表示せずに[Typical]ボタンを押したときと同じ動作をさせる場合は、下記のようにインストーラーを起動させます。
> msiexec INSTALLLEVEL=3 /i Part4_01.msi

[**前の記事へ**](https://qiita.com/tohshima/items/44fa86262e40ec2751a2)　　[**目次へ**](https://qiita.com/tohshima/items/dc4c4721d50a2ad70c7a)　　[**次の記事へ**](https://qiita.com/tohshima/items/9c992f16d08f9b3b962d)

[^1]: これを確認するにはWiXのソースにあるファイル[src/ext/UIExtension/wixlib/SetupTypeDlg.wxs](https://github.com/wixtoolset/wix3/blob/wix3111rtm/src/ext/UIExtension/wixlib/SetupTypeDlg.wxs)を見る必要があります。WiXのドキュメントに書いて欲しいところです。
[^2]: これは全部大文字であることからも読み取れますね。