Windows Installer手引書 Part.3 Directory

[**前の記事へ**](https://qiita.com/tohshima/items/88a41ffcdbfaa18f3edc)　　[**目次へ**](https://qiita.com/tohshima/items/dc4c4721d50a2ad70c7a)　　[**次の記事へ**](https://qiita.com/tohshima/items/1788a01745c631157a77)

# Directory
## Directoryエレメントの使い方
Windows InstallerでDirectoryを定義する際には、必ずルートをTARGETDIRというIdで作成します。引き続きPart.2で例示したフォルダ構造を使います。
![Part3Fig01.png](https://qiita-image-store.s3.amazonaws.com/0/83170/d05d14eb-91e6-8c9e-8ac6-263d51e8e78f.png)
この構造をWiXのソースで表現すると、例えば次のように書くことができます。

```xml
 1: <Directory Id="TARGETDIR" Name="SourceDir">
 2:   <Directory Id="ProgramFilesFolder">
 3:     <Directory Id="PRODUCT1FOLDER" Name="Product1">
 4:       <Directory Id="DataFolder" Name="Data" />
 5:     </Directory>
 6:   </Directory>
 7: </Directory>
```

１行目はどのインストーラーにも存在する決まり文句です。Directoryエレメントが構成する階層構造のルートのIdは必ずTARGETDIRプロパティ[^1]です。SourceDir[^1]はインストールを実行したときに、インストール物のファイルをどのフォルダからコピーしてくるか指定するプロパティです。インストール実行時にカスタムアクションで内容を変更することも可能ですが、".cab"ファイルの置き場所もMediaエレメントで制御できるので、利用する機会はないでしょう。

２行目はシステムで定義済みのProgramFilesFolderプロパティを指定します。システムで定義済みのプロパティは、[System Folder Properties](https://docs.microsoft.com/en-us/windows/desktop/msi/property-reference#system-folder-properties)に一覧があります。この一覧を見れば分かるように、Windows Installerでは使えるフォルダが少なく困ることもあります[^2]。そのようなときは、[WiXがシステムからパスを取得する仕組みを用意している](http://wixtoolset.org/documentation/manual/v3/customactions/osinfo.html)ので、これを使います。例えば、共有ドキュメントへのパスが欲しいときは次のようにします。
Visual Studioのプロジェクトの下のReferencesの下にWixUtilExtension.dll[^3]を追加。
![Part3Fig02.png](https://qiita-image-store.s3.amazonaws.com/0/83170/47c381ff-7834-b5a7-6185-f6f8da7db462.png)
そして、WiXのソースに下記の行を追加。

```xml
<PropertyRef Id="WIX_DIR_COMMON_DOCUMENTS" />
```

これだけで、共有ドキュメントへのパスが格納されたWIX_DIR_COMMON_DOCUMENTSプロパティが利用可能になります。Directoryエレメントで利用する際には、Idにこのプロパティを指定します。他のパスも必要であれば、PropertyRefエレメントを追加していきます。利用可能なプロパティは[こちら](http://wixtoolset.org/documentation/manual/v3/customactions/osinfo.html)を参照してください。

３行目のIdは全て大文字で名付けてあります。こうするとId部分がPublic Propertyとして扱われ、msiexecのコマンドラインにパスを指定できるようになります。この仕組みを利用することで、フォルダのパスを".msi"の外部から与えることが可能になります。例えば下記の様にインストールを開始します。

> msiexec PRODUCT1FOLDER=C:&yen;TESTDIR /i Part3_01.msi

そうすると、下図のようにインストールされます。
![Part3Fig01.png](https://qiita-image-store.s3.amazonaws.com/0/83170/b49e3777-29a5-3955-5971-367ae3c93fb9.png)
Directoryエレメントの階層構造を構成する上で基本的な考え方は次のようになります。

- 階層のルートはIdがTARGETDIRの決まり文句を配置
- その子階層にシステムが定義するプロパティをIdにしてDirectoryエレメントを配置
- その子階層にインストールする製品が必要としている名前でDirectoryエレメントを配置

## 32bit版Windowsと64bit版Windowsで利用可能なDirectory

Windows Installerを利用したインストーラーでは、32bit版Windowsと64bit版Windowsの両方で利用可能な32bit版インストーラーと、64bit版Windowsだけで利用可能な64bit版インストーラーが存在します。32bit版インストーラーを64bit版Windowsで利用すると、64bit用のフォルダや64bit用のレジストリにアクセスできません。そのため、システムが定義するプロパティのうち64bit版が存在するものには注意が必要です。以下にProgramFilesFolderとProgramFiles64Folderの例を示します。

- ProgramFilesFolderプロパティが指し示すパス

|   |32bit版Windows|64bit版Windows|
|:-:|:-:|:-:|
|32bit版インストーラー|C:&yen;Program Files|C:&yen;Program Files (x86)|
|64bit版インストーラー|インストーラー<br>起動不可|C:&yen;Program Files (x86)|

- ProgramFiles64Folderプロパティが指し示すパス

|   |32bit版Windows|64bit版Windows|
|:-:|:-:|:-:|
|32bit版インストーラー|プロパティ<br>利用不可[^4]|プロパティ<br>利用不可[^4]|
|64bit版インストーラー|インストーラー<br>起動不可|C:&yen;Program Files|

Windows Installerにはこのような制約があるため、32bit版インストーラーと64bit版インストーラーの両方を作成することもあります。さらに製品として配布するために、OSが32bit版か64bit版か判別して適切なインストーラーを起動する、セットアップランチャーを開発することもあります。

[**前の記事へ**](https://qiita.com/tohshima/items/88a41ffcdbfaa18f3edc)　　[**目次へ**](https://qiita.com/tohshima/items/dc4c4721d50a2ad70c7a)　　[**次の記事へ**](https://qiita.com/tohshima/items/1788a01745c631157a77)

[^1]: システムが定義済みなので、自分で定義する必要はありません。
[^2]: 私は共有ドキュメントのパスが取得できなくて困りました。このときはよく調べもせず、C言語でカスタムアクションを書いて解決しました。
[^3]: `C:\Program Files (x86)\WiX Toolset v3.11\bin`にあります。
[^4]: 64bit指定しないComponentでDirectoryとして利用するとエラーでコンパイルできない。そして、Componentを64bit指定すると、インストーラー全体を64bit版に指定しないとコンパイルできない。結局32bit版インストーラーでは利用できないのです。