CX5 SOFTWARE

WiX (Windows Installer XML)

2009.9.6


目次

1. はじめに
1.1. WiX(Windows Installer XML)のインストール
1.1.1. Votiveのインストール
1.1.2. WiX toolsetのインストール
2. 簡単なインストーラの作成
3. ライセンス認証とインストール先を指定できるインストーラ
3.1. Productタグの属性の変更
3.2. Packageタグの属性の変更
3.3. Directoryタグの変更
3.4. Program Filesフォルダへコピーするファイルの指定
3.5. プログラムメニューへのショートカットの作成
3.6. Featureの指定
3.7. UIの指定
3.8. テスト

第1章 はじめに

Windowsアプリケーションを開発した場合、できればインストーラ形式にしたいと誰でも思うと思います。でも、結構、これが難しい。

まず、そもそもどうやってインストーラを作成するかを選ばなければならない。いろいろと方法がある必要がないとも思うのだが...。最初の方法は、インストーラを作成するパッケージソフトを使うという方法。有名なのはInstallShieldやWiseといったところでしょうか。ただ、値段はそこそこして、企業ならば問題ないだろうけど、個人ではなかなか買えない。

次にオープンソースのインストーラですが、有名なのがNSIS(Nullsoft Scriptable Install System)です。自分も以前は何回かNSISでインストーラを作成しました。

最近になって注目されているのがWiX(ウィックス)です。マイクロソフトもMicrosoft Windows Installerとしてインストーラの共通の仕組みを提供しているのですが、それを簡単に開発できるのがWiXです。WiX自体もマイクロソフトが中心で開発していますが、マイクロソフト初のオープンソースプロジェクトとして開発されています。WiXをいろいろと試してみていますので、その内容についてまとめてみました。

1.1. WiX(Windows Installer XML)のインストール

WiX(Windows Installer XML)はオープンソースということで、SourceForgeで管理されています。プロジェクトのメインページはこちらです。

WiXを利用できるようにするには、WiX toolsetをインストールする必要がありますが、その前に、WiXの開発環境をどうするかを考える必要があります。WiXプロジェクトとでは、VotiveというVisual StudioをWiXの開発環境として使えるようにするツールも用意しています。Visual Studio 2005もしくは2008を持っている場合は、こちらを用いた方がよいでしょう。ただし、VotiveはExpress Editionでは動作しません。その場合は、テキストエディタで編集したものをコマンドラインからインストーラを生成することになります。(いくつか、WiX用のエディタがあるようですので、そちらを試してみてもよいかもしれません)

1.1.1. Votiveのインストール

Visual Studioを用いて開発する場合は、最初にVotiveをインストールしてください(WiX toolsetを最初にインストールしようとすると警告が表示されます)。VotiveのパッケージであるProjectAggregator2.zipをここよりダウンロードします。解凍後、インストーラを起動することでVisual Studioに拡張機能が追加されます。以下はVisual Studio 2005で新規プロジェクトを作成するダイアログを開いたところです。

1.1.2. WiX toolsetのインストール

WiX toolsetをここよりダウンロードしてください。現時点ではwix3.0.5419.0-x86-setup.zipが最新でした。ZIPを解凍後、インストーラを起動しインストールします。

第2章 簡単なインストーラの作成

最初に、細かい説明は抜きにして、簡単なインストーラを作成してみます。最初に、Visual Studioを起動し「ファイル」-「新規プロジェクト」で、以下のように「WiX Project」を選択します。プロジェクト名は「WiXProject_1」としました。

すると、「Product.wxs」というファイルが自動的に生成されます。この拡張子wxsのファイルが、WiXの用いるインストーラの内容を定義するものです。「Product.wxs」の内容は以下のようになっているはずです。

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
	<Product Id="<ここにGUIDが自動的に設定されます>" Name="WixProject_1" Language="1033" Version="1.0.0.0" Manufacturer="WixProject_1" UpgradeCode="<ここにGUIDが自動的に設定されます>">
		<Package InstallerVersion="200" Compressed="yes" />

		<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />

		<Directory Id="TARGETDIR" Name="SourceDir">
			<Directory Id="ProgramFilesFolder">
				<Directory Id="INSTALLLOCATION" Name="WixProject_1">
					<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
					<!-- <Component Id="ProductComponent" Guid="xxxxx"> -->
						<!-- TODO: Insert files, registry keys, and other resources here. -->
					<!-- </Component> -->
				</Directory>
			</Directory>
		</Directory>

		<Feature Id="ProductFeature" Title="WixProject_1" Level="1">
			<!-- TODO: Remove the comments around this ComponentRef element and the Component above in order to add resources to this installer. -->
			<!-- <ComponentRef Id="ProductComponent" /> -->
		</Feature>
	</Product>
</Wix>

ただし、ProductタグのIdとUpgradeCodeにはGUIDと呼ばれるIDが自動的に生成されて設定されます。

このままでも、何もしないインストーラですが、一応インストーラが生成できます。「ビルド」-「ソリューションのビルド」を実行することで、「WixProject_1.msi」というファイルが、「WixProject_1\bin\Debug」フォルダ内に生成されます。

この生成されインストーラ「WixProject_1.msi」を起動すると、一瞬ですがダイアログが表示されインストールが完了されます。「Program Files」フォルダを開くと「WixProject_1」というフォルダが作成されているのが確認できます。

さらに、コントロールパネルの「プログラムのアンインストール」を選択すると、一覧に「WixProject_1」が表示されます。実際にアンインストールすることもできます。

第3章 ライセンス認証とインストール先を指定できるインストーラ

では次に、もう少し実践的なライセンス認証とインストール先を指定できるインストーラを作成してみましょう。ここで作成するインストーラは、EXEがアプリケーション全体で一つしかないような小さなプロジェクトで使えるものです。

先ほどと同じようにVisual Studioで新しいWixプロジェクトを作成します。以下が自動的に生成されたWXSファイルです。

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
	<Product Id="<ここにGUIDが自動的に設定されます>" Name="WixProject2" Language="1033" Version="1.0.0.0" Manufacturer="WixProject2" UpgradeCode="<ここにGUIDが自動的に設定されます>">
		<Package InstallerVersion="200" Compressed="yes" />

		<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />

		<Directory Id="TARGETDIR" Name="SourceDir">
			<Directory Id="ProgramFilesFolder">
				<Directory Id="INSTALLLOCATION" Name="WixProject2">
					<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
					<!-- <Component Id="ProductComponent" Guid="..."> -->
						<!-- TODO: Insert files, registry keys, and other resources here. -->
					<!-- </Component> -->
				</Directory>
			</Directory>
		</Directory>

		<Feature Id="ProductFeature" Title="WixProject2" Level="1">
			<!-- TODO: Remove the comments around this ComponentRef element and the Component above in order to add resources to this installer. -->
			<!-- <ComponentRef Id="ProductComponent" /> -->
		</Feature>
	</Product>
</Wix>

3.1. Productタグの属性の変更

最初に、いくつか細かな設定を行います。2行目にあるProductタグには、NameやLanguage等の重要な属性がありますので、これらを変更します。説明が必要なのはLanguageとCodepageでしょう。Languageの1041は日本語を、Codepageの932は文字コードを指定しています。

<Product Id="<ここにGUIDが自動的に設定されます>"
         Name="Wix_Sample2"
         Language="1041"
         Codepage="932"
         Version="1.0.0.0"
         Manufacturer="yy2"
         UpgradeCode="<ここにGUIDが自動的に設定されます>">

3.2. Packageタグの属性の変更

同じように3行目にあるPackageタグに属性の追加と変更を行います。

<Package InstallerVersion="200"
         Compressed="yes"
         Languages="1041"
         SummaryCodepage="932"
         Description="Wixインストーラサンプル2"
         Manufacturer="yy2"/>

3.3. Directoryタグの変更

Directoryタグは、インストーラがファイルをコピーしたりショートカットを作成したりするフォルダを指定します。今回作成するインストーラでは、「Program Files」フォルダとスタートメニューにショートカットを作成するためのフォルダの2つを作成します。

<Directory Id="TARGETDIR" Name="SourceDir">
    <Directory Id="ProgramFilesFolder">
      <Directory Id="INSTALLLOCATION" Name="Wix_Sample2"/>
    </Directory>
    <Directory Id="ProgramMenuFolder">
        <Directory Id="APPLICATIONPROGRAMFOLDER" Name="Wix_Sample2"/>
    </Directory>
</Directory>

ここで注意しなければならないのがIDに指定されている一見普通の文字列に見える「ProgramFilesFolder」と「ProgramMenuFolder」です。 ProgramFilesFolderは、Program Filesフォルダへの完全パスを表すプロパティです。 ProgramMenuFolderは、プログラムメニューフォルダへの完全パスを表すプロパティです。

INSTALLLOCATIONとAPPLICATIONPROGRAMFOLDERは、特別なIDではなく、後で参照するためにここで指定したIDです。

3.4. Program Filesフォルダへコピーするファイルの指定

Program Filesフォルダへコピーするファイルを指定するにはComponentタグを用います。Componentタグでコピーするファイルを指定しますが、その際に、どのディレクトリにコピーするかを指定するためにDirectoryRefタグで囲みます。DirectoryRefタグは、以前指定したDirectoryタグを参照するために使われます。今回の場合、Program Filesフォルダを指定しなければなりませんのでIDとしてINSTALLLOCATIONを指定します。

<DirectoryRef Id="INSTALLLOCATION">
      <Component Id="WixSample2.vbs" Guid="<GUIDGENでGUIDを生成してここにコピーします>">
        <File Id="WixSample2.vbs" Name="WixSample2.vbs" DiskId="1" Source="WixSample2.vbs" KeyPath="yes"/>
      </Component>
      <Component Id="LICENSE.rtf" Guid="<GUIDGENでGUIDを生成してここにコピーします>">
        <File Id="LICENSE.rtf" Name="LICENSE.rtf" DiskId="1" Source="LICENSE.rtf" KeyPath="yes"/>
      </Component>
</DirectoryRef>

ここでは、WixSample2.vbsというVBScriptファイルと、ライセンス条項を記述したLICENSE.rtfをコピーしています。

WixSample2.vbsの内容は以下のようにしています。(本来は、インストールしたいEXEファイル等を指定します。)

MsgBox "Wix Sample2!"

LICENSE.rtfは、ライセンス条項を記述したRTF(Rich Text File)です。ワードパッドやWordで作成してください。

3.5. プログラムメニューへのショートカットの作成

プログラムメニューへは、WixSample2.vbsを起動するためのショートカットと、アンインストーラのショートカットを作成します。

プログラムメニューへショートカットを作成するためには、ComponentタグとShortcutタグを用います。その際、先ほどのProgram Filesと同様にプログラムフォルダを参照するためにDirectoryRefタグにIDとしてAPPLICATIONPROGRAMFOLDERを指定し、その子要素としてComponentとShortcutタグを記述します。

<DirectoryRef Id="APPLICATIONPROGRAMFOLDER">
      <Component Id="ApplicationShortcut" Guid="<GUIDGENでGUIDを生成してここにコピーします>">
        <Shortcut Id="ApplicationStartMenuShortcut1"
                  Name="Wix_Sample2"
                  Description="Wix Sample2です"
                  Target="[INSTALLLOCATION]WixSample2.vbs"
                  WorkingDirectory="INSTALLLOCATION"/>
        <Shortcut Id="UninstallProduct"
                  Name="Uninstall Wix_Sample2"
                  Description="Wix Sample2をアンインストールします"
                  Target="[System64Folder]msiexec.exe"
                  Arguments="/x [ProductCode]"/>
        <RemoveFolder Id="APPLICATIONPROGRAMFOLDER" On="uninstall"/>
        <RegistryValue Root="HKCU" Key="Software\yy2\Wix_Sample2" Name="installed"
                       Type="integer" Value="1" KeyPath="yes"/>
      </Component>
</DirectoryRef>

まず、WixSample2.vbsへのショートカットですが、以下のように指定します。Target属性の[INSTALLLOCATION]が、先ほどDirectoryタグで指定したProgram Filesフォルダを指していることがわかれば難しくないと思います。

<Shortcut Id="ApplicationStartMenuShortcut1"
          Name="Wix_Sample2"
          Description="Wix Sample2です"
          Target="[INSTALLLOCATION]WixSample2.vbs"
          WorkingDirectory="INSTALLLOCATION"/>

次にアンインストーラへのショートカットですが、以下のように指定します。こちらは、WiXのドキュメントに書かれているように記述しています。注意するのは、RegistryValueでレジストリにキーを追加しています。Key属性に指定する値を、「Software\組織名\プログラム名」となるように変更してください。

<Shortcut Id="UninstallProduct"
          Name="Uninstall Wix_Sample2"
          Description="Wix Sample2をアンインストールします"
          Target="[System64Folder]msiexec.exe"
          Arguments="/x [ProductCode]"/>
<RemoveFolder Id="APPLICATIONPROGRAMFOLDER" On="uninstall"/>
<RegistryValue Root="HKCU" Key="Software\yy2\Wix_Sample2" Name="installed"
               Type="integer" Value="1" KeyPath="yes"/>

3.6. Featureの指定

Featureは、Officeのような大きなアプリケーションでオプション機能を指定する際に、複数のファイルで構成される1つの機能を指定するために使います。つまり、複数の機能で構成される場合は複数のFeatureを指定します。しかし、ここで作成しているインストーラは単一の機能しかなく、機能を選択する画面も表示しませんので、以下のようにひとつのFeatureを指定します。

    <Feature Id="ProductFeature" Title="Wix_Sample2" Level="1">
      <ComponentRef Id="WixSample2.vbs"/>
      <ComponentRef Id="LICENSE.rtf"/>
      <ComponentRef Id="ApplicationShortcut"/>
    </Feature>

Featureタグの中に、今まで指定したComponentタグをComponentRefタグを用いて指定します。

3.7. UIの指定

WiXには、一般的に使われるUIが拡張機能として含まれています。拡張機能のためそのままでは使うことはできず、ビルドする際のオプションとして「-ext WixUIExtension」を指定する必要があります。

Visual Studioの場合、プロジェクトのプロパティを表示し、Tool SettingsタブのLinkerオプションに以下のように指定します。さらにここでは、UIのボタン等が日本語化されるようにするため「-loc WixUI_ja-jp.wxl」も指定しています。

コマンドラインからLight.exeを起動している場合は、同様にオプションとして「-ext WixUIExtension -loc WixUI_ja-jp.wxl」を指定します。

WiXでは、UIをロケールに合わせて変更できるようになっています。その設定が含まれているのがlocオプションで指定した「WixUI_ja-jp.wxl」というファイルです。この「WixUI_ja-jp.wxl」はWiXのソースコードをダウンロードすることで取得することができます。(WiXのマニュアルを参照すると日本語は、WiX内に含まれているように思われるので「WixUI_ja-jp.wxl」を別途ダウンロードする必要はないように思えるのですが、いろいろと試しましたがうまくいかず、locオプションで指定する方法にしています。)

最後にUIとして何を表示するかの設定を追加します。

    <UIRef Id="WixUI_InstallDir"/>
    <UIRef Id="WixUI_ErrorProgressText" />
    <Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION" />
    <WixVariable Id="WixUILicenseRtf" Value="LICENSE.rtf"/>

ここでは、インストールフォルダを指定できるようにすることと、ライセンス認証画面表示時にLICENSE.rtfを表示するように指定しています。

3.8. テスト

以上で、設定は完了です。完全なWXSファイルの内容を以下に示します。

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
	<Product Id="<ここにGUIDが自動的に設定されます>"
           Name="Wix_Sample2"
           Language="1041"
           Codepage="932"
           Version="1.0.0.0"
           Manufacturer="yy2"
           UpgradeCode="<ここにGUIDが自動的に設定されます>">
    
    <Package InstallerVersion="200"
             Compressed="yes"
             Languages="1041"
             SummaryCodepage="932"
             Description="Wixインストーラサンプル2"
             Manufacturer="yy2"/>

    <Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />

    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLLOCATION" Name="Wix_Sample2"/>
      </Directory>
      <Directory Id="ProgramMenuFolder">
        <Directory Id="APPLICATIONPROGRAMFOLDER" Name="Wix_Sample2"/>
      </Directory>
    </Directory>

    <DirectoryRef Id="INSTALLLOCATION">
      <Component Id="WixSample2.vbs" Guid="<GUIDGENでGUIDを生成してここにコピーします>">
        <File Id="WixSample2.vbs" Name="WixSample2.vbs" DiskId="1" Source="WixSample2.vbs" KeyPath="yes"/>
      </Component>
      <Component Id="LICENSE.rtf" Guid="<GUIDGENでGUIDを生成してここにコピーします>">
        <File Id="LICENSE.rtf" Name="LICENSE.rtf" DiskId="1" Source="LICENSE.rtf" KeyPath="yes"/>
      </Component>
    </DirectoryRef>

    <DirectoryRef Id="APPLICATIONPROGRAMFOLDER">
      <Component Id="ApplicationShortcut" Guid="<GUIDGENでGUIDを生成してここにコピーします>">
        <Shortcut Id="ApplicationStartMenuShortcut1"
                  Name="Wix_Sample2"
                  Description="Wix Sample2です"
                  Target="[INSTALLLOCATION]WixSample2.vbs"
                  WorkingDirectory="INSTALLLOCATION"/>
        <Shortcut Id="UninstallProduct"
                  Name="Uninstall Wix_Sample2"
                  Description="Wix Sample2をアンインストールします"
                  Target="[System64Folder]msiexec.exe"
                  Arguments="/x [ProductCode]"/>
        <RemoveFolder Id="APPLICATIONPROGRAMFOLDER" On="uninstall"/>
        <RegistryValue Root="HKCU" Key="Software\yy2\Wix_Sample2" Name="installed"
                       Type="integer" Value="1" KeyPath="yes"/>
      </Component>
    </DirectoryRef>

    <Feature Id="ProductFeature" Title="Wix_Sample2" Level="1">
      <ComponentRef Id="WixSample2.vbs"/>
      <ComponentRef Id="LICENSE.rtf"/>
      <ComponentRef Id="ApplicationShortcut"/>
    </Feature>

    <UIRef Id="WixUI_InstallDir"/>
    <UIRef Id="WixUI_ErrorProgressText" />
    <Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION" />
    <WixVariable Id="WixUILicenseRtf" Value="LICENSE.rtf"/>

  </Product>
</Wix>

ビルドすると「WixProject2.msi」が生成されます。

「WixProject2.msi」を起動してみましょう。

インストールが完了するとスタートメニューにショートカットが追加されます。Wix_Sample2を選択して、WixSample2.vbsが起動されるか確認してみてください。

さらに、「Uninstall Wix_Sample2」を選択するとアンインストーラが実行されます。


CX5 SOFTWARE, 2010