SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

WiXではじめるWindows Installer作成入門

WiXではじめるWindows Installer作成入門 第3回

カスタムインストールに対応したインストーラの作成

  • このエントリーをはてなブックマークに追加

本連載は、WiXを利用してインストーラを作成するチュートリアル形式の入門記事です。第3回は、ユーザーインターフェイスつきインストーラ作成のパート2として、カスタムインストールに対応したインストーラを作成します。

  • このエントリーをはてなブックマークに追加

はじめに

 前回は、小規模向けのインストーラでよく利用されている、比較的簡単なUIを使ったインストーラを作成しました。今回は少し規模の大きいカスタムインストールに対応したインストーラを作成します。

対象読者

 インストーラを必要とするすべての開発者。

必要な環境

 前回までと同様、WiX 2.0.4221.0がインストールされた環境。

カスタムインストール対応インストーラを作成する

 前回のインストーラは単純に実行可能ファイルだけを追加していましたが、今回はさらにカスタムインストールに対応したものへと変更します。とはいっても、アプリケーションを改造してプラグインを使えるようにするのは大変なので、単純にサンプルファイルを追加するだけのものとなっています。

 まずは再掲となりますが、UIの種類をもう一度見てみましょう。

WiXのUI種別
UI名略称説明
WixUI_MondoMondo市販ソフトなどでよく見受けられる、標準、カスタム、すべてのインストール形式を選択できるUIシーケンスです。WiXが標準で用意しているUIとしては最も大がかかりな物となります。
WixUI_FeatureTreeFeatureTreeMondoからインストール形式の選択部分を除外し、常にカスタムインストールが行なわれるようになっている形式です。あまり見かけることはありませんが、インストール時に常に何らかの選択肢を必要とするインストーラなどで使われています。
WixUI_MinimalMinimal使用許諾だけが出る、最も少ないUIのインストーラです。カスタムインストールはおろかインストール先の変更もできないため、アドオンなどのようにインストール先の選択が行えないインストーラなどでよく見かけます。
WixUI_InstallDirInstallDirMinimalにインストール先の変更を行えるようにした形のインストーラです。多くのオンラインソフトや、カスタムインストールを必要としないインストーラで利用されている形式です。Visual Studioのセットアッププロジェクトもこの形式と類似した構成になっています。

 今回の記事は、このうち最初の2個を使ってインストーラを作ってみたいと思います。これにより、表記文字列の問題を除いて、かなりの種類のインストーラをフォローできるのではないかと思います。

インストールデータの修正

 前回までのものは、できるだけ一つのブロックにまとめるように階層化した構造にしていたため、構成ごとのまとまりが見づらいものとなっていました。構造的にダメということではありませんが、インストーラの規模が大きくなってくると、所属構成ごとにグループ化した方が全体が見やすく(分割しやすく)なります。プログラムで言うところの構造化をほんの少し進めることで、かなり見やすくなります。

 あくまでも一例ですが、前回の「STEdit3.wxs」の構成をまとめなおしたものを掲載しておきますので、参考にしてください(今回の記事はすべてSTEdit3をベースにしています)。

STEdit3.wxs
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi">
  <Product Id="9F7E5565-F367-4735-91E6-66BD76D47C53" Name="適すとえでぃた"
           Language="1041" Version="1.00.0000" Manufacturer="とっちゃん"
           Codepage="932">
    <Package Id="????????-????-????-????-????????????"
             Description ="適すとえでぃた インストーラ"
             Comments="適すとえでぃた インストーラ"
             InstallerVersion="200" Compressed="yes" Platforms="Intel"
             Manufacturer="とっちゃん" Keywords="Installer,MSI,Database"
             Languages="1041" SummaryCodepage="932" />
    <!-- インストール条件 -->
    <Condition Message="この Windows には [ProductName] 
のインストールはできません">
      <![CDATA[VersionNT > 502 Or (VersionNT = 501 And ServicePackLevel >= 2)]]>
    </Condition>
    <!-- メディア -->
    <Media Id="1" Cabinet="STEdit.cab" EmbedCab="yes" />
    <!-- フォルダ構成 -->
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder" SourceName="PFILE"
                 LongSource="Program Files">
        <Directory Id="INSTALLLOCATION" Name="STEdit"/>
      </Directory>
      <Directory Id="SystemFolder" SourceName="System" LongSource="System32"/>
      <Directory Id="ProgramMenuFolder">
        <Directory Id="AppMenuFolder" Name="STEdit" LongName="適すとえでぃた"/>
      </Directory>
    </Directory>
    <!-- マージモジュール -->
    <Directory Id="SystemFolder" SourceName="System" LongSource="System32">
      <Merge Id="VC80CRTx86.msm" Language="0" DiskId="1"
        SourceFile="$(env.CommonProgramFiles)\Merge Modules\
Microsoft_VC80_CRT_x86.msm"/>
      <Merge Id="POLVC80CRTx86.msm" Language="0" DiskId="1"
        SourceFile="$(env.CommonProgramFiles)\Merge Modules\
policy_8_0_Microsoft_VC80_CRT_x86.msm"/>
    </Directory>
    <!-- コンポーネント -->
    <DirectoryRef Id="INSTALLLOCATION">
      <Component Id="STEdit.exe" Guid="9EC98F2B-2138-4d4e-A97E-10D980061DB6">
        <File Id="STEdit.exe" Name="STEdit.exe" KeyPath="yes" DiskId="1"
              Source="STEdit\release\STEdit.exe" />
        <Shortcut Id="STEdit.exe" Directory="AppMenuFolder" Target="STEdit"
                  Name="STEdit" LongName="適すとえでぃた"
                  Description= "適すとえでぃたを実行します"
                  Icon="STEdit.ico" IconIndex="0" Show="normal">
          <Icon Id="STEdit.ico" SourceFile="STEdit\STEdit\STEdit.ico"/>
        </Shortcut>
        <ProgId Id="STEdit.Document" Description="てきすと ファイル"
                Advertise="yes" Icon="STEditDoc.ico" IconIndex="0">
          <Extension Id="txt" Advertise="yes">
            <Verb Id="Open" Argument=""%1""/>
          </Extension>
        </ProgId>
      </Component>
    </DirectoryRef>
    <!-- ドキュメントアイコン -->
    <Icon Id="STEditDoc.ico" SourceFile="STEdit\STEdit\textdoc.ico"/>

    <!-- インストール機能のツリー構成 -->
    <Feature Id="STEdit" Level="1">
      <Feature Id="MergeModules" Level="1"/>
    </Feature>
    <!-- インストール単位ごとのコンポーネント構成 -->
    <FeatureRef Id="STEdit">
      <ComponentRef Id="STEdit.exe" />
    </FeatureRef>
    <FeatureRef Id="MergeModules">
      <MergeRef Id="VC80CRTx86.msm"/>
      <MergeRef Id="POLVC80CRTx86.msm"/>
    </FeatureRef>
    <!-- ユーザーインターフェイス -->
    <UIRef Id="WixUI_ErrorProgressText" />

    <UIRef Id="WixUI_InstallDir" />
    <Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION" />
  </Product>
</Wix>

インストールデータの追加

 「STEdit3.wxs」までは、インストールするものは全部必須のコンポーネントだけでした。カスタムインストールを行うためには、あってもなくても動くものを用意しておく必要があります(なくても動くという条件がなければカスタマイズすることができません)。プログラムにプラグイン機能などがあればもっと面白いのですが、大掛かりになってしまいますので、単純にサンプルファイルをつけることにしましょう。幸いにも、添付しているSTEditのソリューションの中にテキストファイルがいくつもあるので、それをそのまま添付してしまうことにします。

STEdit4.wxs
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi">
  <?define ProductName = "適すとえでぃた" ?>
  <Product Id="9F7E5565-F367-4735-91E6-66BD76D47C53"
           Name="$(var.ProductName)" Language="1041" Version="1.00.0000"
           Manufacturer="とっちゃん" Codepage="932">
    <Package Id="????????-????-????-????-????????????"
             Description="$(var.ProductName) インストーラ"
             Comments= "$(var.ProductName) インストーラ"
             InstallerVersion="200" Compressed="yes" Platforms="Intel"
             Manufacturer="とっちゃん" Keywords="Installer,MSI,Database"
             Languages="1041" SummaryCodepage="932" />
    <!-- インストール条件 -->
    <Condition Message="この Windows には [ProductName] 
のインストールはできません">
      <![CDATA[VersionNT > 502 Or (VersionNT = 501 And ServicePackLevel >= 2)]]>
    </Condition>
    <!-- メディア -->
    <Media Id="1" Cabinet="STEdit.cab" EmbedCab="yes" />
    <!-- フォルダ構成 -->
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder" SourceName="PFILE"
                 LongSource="Program Files">
        <!-- 追加:サンプルファイルのフォルダを追加 -->
        <Directory Id="INSTALLLOCATION" Name="STEdit">
          <Directory Id="Sample" Name="Sample"/>
        </Directory>
        <!-- 追加:サンプルファイルのフォルダを追加 -->
      </Directory>
      <Directory Id="SystemFolder" SourceName="System" LongSource= "System32"/>
      <Directory Id="ProgramMenuFolder">
        <Directory Id="AppMenuFolder" Name="STEdit"
                   LongName= "$(var.ProductName)"/>
      </Directory>
    </Directory>
    <!-- マージモジュール -->
    <DirectoryRef Id="SystemFolder">
      <Merge Id="VC80CRTx86.msm" Language="0" DiskId="1"
             SourceFile= "$(env.CommonProgramFiles)\Merge Modules\
Microsoft_VC80_CRT_x86.msm"/>
      <Merge Id="POLVC80CRTx86.msm" Language="0" DiskId="1"
             SourceFile="$(env.CommonProgramFiles)\Merge Modules\
policy_8_0_Microsoft_VC80_CRT_x86.msm"/>
    </DirectoryRef>
    <!-- コンポーネント -->
    <DirectoryRef Id="INSTALLLOCATION">
      <Component Id="STEdit.exe" Guid="9EC98F2B-2138-4d4e-A97E-10D980061DB6">
        <File Id="STEdit.exe" Name="STEdit.exe" KeyPath="yes"
              DiskId="1" Source="STEdit\release\STEdit.exe" />
        <Shortcut Id="STEdit.exe" Directory="AppMenuFolder"
                  Target="STEdit" Name="STEdit" LongName="$(var.ProductName)"
                  Description="$(var.ProductName)を実行します"
                  Icon="STEdit.ico" IconIndex="0" Show="normal">
          <Icon Id="STEdit.ico" SourceFile="STEdit\STEdit\STEdit.ico"/>
        </Shortcut>
        <ProgId Id="STEdit.Document" Description="てきすと ファイル"
                Advertise="yes" Icon="STEditDoc.ico" IconIndex="0">
          <Extension Id="txt" Advertise="yes">
            <Verb Id="Open" Argument=""%1""/>
          </Extension>
        </ProgId>
      </Component>
    </DirectoryRef>
    <!-- 追加:サンプルファイル -->
    <DirectoryRef Id="Sample">
      <Component Id="ReadMe.txt" Guid="6CAD3B4C-A69B-4f0b-BA8D-A390E18BDC41">
        <File Id="ReadMe.txt" Name="Sample.txt" KeyPath="yes"
              DiskId="1" Source="STEdit\STEdit\ReadMe.txt"/>
      </Component>
      <Component Id="STEdit.txt" Guid="{50F7E246-0901-4f15-B9CA-A76A33256A67}">
        <File Id="STEdit.txt" Name="STEdit.txt" KeyPath="yes"
              DiskId="1" Source="STEdit\STEdit\STEdit.cpp"/>
      </Component>
    </DirectoryRef>
    <!-- ドキュメントアイコン -->
    <Icon Id="STEditDoc.ico" SourceFile="STEdit\STEdit\textdoc.ico"/>

    <!-- インストール機能のツリー構成 -->
    <Feature Id="System" Level="1" Display="hidden"/>
      <Feature Id="STEdit" Level="1" Title="$(var.ProductName)"
               Description="$(var.ProductName) の実行ファイル"
               AllowAdvertise="no" Display="expand"
               ConfigurableDirectory= "INSTALLLOCATION" Absent="disallow">
      <!-- 追加:サンプル -->
      <Feature Id="Sample" Level="1" Title="サンプルファイル"
               Description="$(var.ProductName) のサンプルファイル">
        <Feature Id="Sample1" Level="1" Title="サンプル1"
                 Description="$(var.ProductName) のサンプル1"
                 AllowAdvertise="no"/>
        <Feature Id="Sample2" Level="1" Title="サンプル2"
                 Description="$(var.ProductName) のサンプル2"/>
      </Feature>
      <!-- 追加:サンプル -->
    </Feature>
    <!-- インストール単位ごとのコンポーネント構成 -->
    <FeatureRef Id="System">
      <MergeRef Id="VC80CRTx86.msm"/>
      <MergeRef Id="POLVC80CRTx86.msm"/>
    </FeatureRef>
    <FeatureRef Id="STEdit">
      <ComponentRef Id="STEdit.exe" />
    </FeatureRef>
    <!-- 追加:サンプル -->
    <FeatureRef Id="Sample1">
      <ComponentRef Id="ReadMe.txt"/>
    </FeatureRef>
    <FeatureRef Id="Sample2">
      <ComponentRef Id="STEdit.txt"/>
    </FeatureRef>
    <!-- 追加:サンプル -->
    <!-- ユーザーインターフェイス -->
    <UIRef Id="WixUI_ErrorProgressText" />
    <UIRef Id="WixUI_FeatureTree" />
  </Product>
</Wix>

 この「STEdit4.wxs」を使うと、インストール中に次のような画面が出て、インストールするものを選択できるようになります。

FeatureTree
FeatureTree

 この画面上で、ハードディスクの絵のマークのあるところをクリックすると、ドロップダウンメニューが出てきます。あえて場所ごとに違うメニューが出るような構成で作成してありますので、いろいろと試してみてください。

Featureのツリー構成

 Windows Installerのカスタムインストールは、Featureのツリー構造をそのまま表現手段として利用しています。ソースファイルでは「インストール機能のツリー構成」のコメントの部分でこのツリーを構成する形になっています。ツリーの順番は、XML上での順番に一致するようになっています。また、表示するかどうかや、ツリーを展開した状態にするかどうかは、Display属性で指定するようになっています。表示しないFeatureについては、Title/Description/ConfigurableDirectoryの3つの属性は必要ありません。また表示する場合でも、そのFeatureのインストール先を変更できないような場合は、ConfigurableDirectory属性をつけないという手段もあります(これ自体は、ツリー表示ダイアログでアイテム選択時にフォルダを指定できるようにするかどうかというオプション機能です)。うまく活用することでダイアログを変更しなくとも、いろいろな構成を表現することができるので、研究してみてください。

Featureとは
 ユーザーがカスタマイズ可能な、インストール単位として用意されていますが、実際はそれだけではありません。Windows InstallerのFeatureは、階層がより上位(トップレベルに近いもの)のものほど、基本機能とみなし、より下層のものになるに従ってその拡張機能であるとみなします。今回の例で言えば、Sampleなどは、拡張機能として用意されたものですし、逆にSystemはアプリケーションの動作に必須のものとなるため、親として切り出しています(そして見えるようになっていません)。通常この規模であればここまで細かく切り分けるようなことはしません。今回はサンプルとしてわざと別のものとして配置していることをご理解ください。
 Featureには他にも重要な仕組みがあります。今回のサンプルではアドバタイズ機能は利用していませんが、アドバタイズインストールの単位も、Feature単位になります。プラグインなどでアドバタイズインストールに対応する場合は、Featureとして分けることで、より優位性が見出せます。また、自動修復の対象もFeatureになっているため、そういった面からも、動作に必要なものはできる限り、1つのFeatureとしてまとめておくことが重要となります。もちろん、それを逆手に取った管理もテクニックの1つではあるのですが。

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

次のページ
Mondo UIを利用する

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加
WiXではじめるWindows Installer作成入門連載記事一覧

もっと読む

この記事の著者

とっちゃん(トッチャン)

Microsoft MVP for Development Tools Visual C++Windows Installer 系を中心にオンライン/オフラインで活動しています。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/507 2006/09/05 00:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング