はじめに
連載第5回までで、インストーラ本体の開発はほぼ完了しましたが、まだアップデートへの対応ができていません。今回は最終回として、アップデートの種類の解説し、実際にメジャーアップグレードの形式で新バージョンのインストーラの作成を行いたいと思います。
過去の回
- 第1回:Windows Installer XML(WiX) toolsetを利用したmsiの作成
- 第2回:簡易ユーザーインターフェイスを持つインストーラの作成
- 第3回:カスタムインストールに対応したインストーラの作成
- 第4回:ユーザー情報入力画面の作成とシリアル番号の検証
- 第5回:独自のシリアル番号検証ルーチンの作成
サンプルの構成
- STEditV100.zip:ファーストリリースとなる製品インストーラ
- STEditV110.zip:バージョンアップ版となる製品インストーラ
- CA_ValidPID.zip:Ver.1.00/1.10 の全ソース
対象読者
インストーラを必要とするすべての開発者。
必要な環境
連載では、WiX 2.0.4103.0以降を対象としていますが、原則として原稿執筆時点での最新版を利用しています。
原稿執筆時(2006/12/19)の最新ビルドは2.0.4611.0となっています。
製品のアップデートとは
作成した製品に、一切バグがなく、出荷後の変更要求もなし、OSの変化(毎月のようにアップデートがありますし、SP2のような大きな変更が行われることもあります)や、ドライバの不具合にも影響を受けないような素晴らしい製品を作ることができれば、アップデートについては考慮する必要はないでしょう。
ですが現実には、完全にバグを取り除くことはなかなか難しいものがありますし、OSの変更(特にメジャーバージョンアップであればその影響力は計り知れないものがあります)、あるいはドライバの不具合に起因するものや、極端な例ではほかの製品(特に常駐ソフト)との相性などで、不具合が発生することがあるのが実情です。こういった事情もあるため、Windows Installerにも更新のための仕組みが用意されています。まずはこの仕組みについて少し細かい話を行いたいと思います。
Windows Installerにおける製品管理と更新について
Windows Installerは4つの製品識別情報(ProductCode, ProductName, ProductVersion, PackageCode)と、1つの製品更新管理情報(UpgradeCode)の5つのプロパティ情報と、msiファイル名で製品を管理しています。これらはすべて固有の意味を持っており、下記の表のように管理されています。
製品識別子 | 説明 |
ProductCode | 製品のシステム識別子として定義されている。インストールされているかどうかの検出など、あらゆる場面でインストール製品の個体識別を行う際の識別子として利用され、インストール製品管理情報(コントロールパネルの追加と削除を実現するための管理データ)の内部識別子としても用いられる。 |
ファイル名 | インストール製品のパッケージファイルの実体参照に用いられる。追加、修復あるいは更新するなど、元のパッケージファイルを参照する必要がある場合の実体識別子でもあり、ProductCodeが一致する限り必ず同一ファイル名を用いなければならない。ファイル名はOSの環境に影響を受けづらい8文字の英数字(と一部記号)で構成されたファイル名が望ましいとされているが必ずしも、8文字以下でなければならないわけではない。 |
ProductName | 製品の表示名としてシステムで一意に扱われる。人が認識するものではあるが、インストール時に固定データとして内容を書き込んでしまうため、ProductCodeと同様の扱いを受ける(名称重複は不問)。これら3種類は、必ずProductCodeの管理と合わせ、外部に出た時点以後、ProductCodeを同じにする限り常に同じものとしなければならない(正式版出荷後であれば、絶対不変のものとして扱わなければならない)。 |
ProductVersion | 製品のインストールバージョンとして管理される。通常はインストール対象の主製品と同じバージョンを用いる。ProductVersion プロパティは、3つのブロックで管理されており、major.minor.buildの値で管理される(ファイルバージョンとは異なり、4つ目以降は無視される)。major, minorは255まで、buildは65535までの数値(もちろん0以上)で管理されるが、すべて0はNGとされている。 |
PackageCode | 正確にはインストーラプロパティではなく、SummaryInformation プロパティになる。この値は、パッケージファイル識別子とも呼ばれており、ビルドしたmsiファイルの個体識別に利用されている。そのため、この値が同じ場合はたとえ中身が異なっていようともファイルは一致するものとして扱われる。非常にデリケートな性格をもったプロパティでもある。 |
UpgradeCode | 特定の1製品のライフサイクルを管理する際に用いられるアップグレード時の検索コードとして用意されている。この値を持つものは、将来アップグレードが可能とされており(ただし、提供しなければならないわけではない)、将来の更新計画がはっきりしていない場合でも、更新の可能性がわずかでもある限り設定しておく必要のあるプロパティとされている。このプロパティがある限り、理不尽と思えるような更新計画が発生した場合でも対応することができる可能性が残される。 |
これらの識別子のうち、…Codeとなっている3つは、いずれもGUIDを識別子として利用しています。個々のコードでの重複は特に言及されてはいませんが、それぞれに一意な値を用意する必要があります。またこれらの識別子はUpgradeCodeを除き、必ずすべてのインストーラで定義されています。
アップデート規模による違い
Windows Installerではアップデート方法とその規模により、次のような構成が用意されています。それぞれは同じようなものという見方もありますが、微妙に異なる更新スタイルになっていますので、使わない場合も含めきちんと把握しておくことをお勧めします。
Small Updates(スモールアップデート)
MSアップデータ用語としては、QFE(Quick Fix Engineering)と呼ばれるものに相当します。修正内容自体がごくわずか(いくつも含まれるモジュールの1つだけなど)な場合に利用されることがあります。Windows Installerでは、上述した識別子のうち、PackageCodeだけが異なるものを指します。
Minor Upgrades(マイナーアップグレード・マイナーアップデートとも呼ばれる)
MSアップデータ用語としては、SP(Service Pack)と呼ばれるものに相当します。修正は多岐にわたるものの、バージョンアップとは異なりバグフィックスが中心的なものとなります。Windows Installerでは、上述した識別子のうち、PackageCodeとProductVersionが異なるものとなります。実際は、Small UpdatesとMinor Upgradesの違いは、ProductVersionが同じか同じではないかの違いだけですが、バージョンを更新するため、呼び名が違っています。
Major Upgrades(メジャーアップグレード)
Office 2003からOffice 2007への更新など、いわゆるバージョンアップと呼ばれるものを指します。実際は修正版であっても上述のアップデートでは適用できない変更内容であったり、戦略的なバージョンアップなどで利用される場合もあります。Windows Installerでは、上述した識別子のうち、原則としてUpgradeCodeだけが同じものとなります(UpgradeCodeが異なるメジャーアップグレードも可能ですが、通常はこのようなアップグレードは行いません)。こちらは、上述の2つとは異なり、ProductCodeが違うため、別のインストールセットを作り、新しいバージョンをインストールする際にインストール済みの古いバージョンをアンインストールするという仕組みで動作します。そのため、バージョンアップに関する制限事項が少ないという利点があります。
アップデータの提供形態による違い
Patching(パッチ)
文字通り修正を当てる(=patching)もので、mspの拡張子を持つ更新専用インストーラを提供するものとなります。こちらはインストール済みのものを更新するため、インストールされていない環境で動かすことはできません。Windows Installerでは、パッチで提供可能なものは、Small UpdatesまたはMinor Upgradesの2種類だけとなります。Major Upgradesは提供できません(この連載では扱いません)。
Upgrades(アップグレード)
こちらはmsi形式でかつ更新可能な形で提供するインストーラとなります。メジャーアップグレードの場合は、通常のインストーラ呼び出しで動作しますが、マイナーアップグレード(スモールアップデートを含む)の場合は、更新再インストールする必要があります(REINSTALL=ALL REINSTALLMODE=vomusを設定してインストーラを実行する)。また、インストールされていない場合は、新規インストールができるというメリット(場合によってはデメリット)があります。
ファーストリリースのための最後の仕事
この連載でこれまで作成してきたアプリケーションは、まだ初回リリースには至っていません(とお考えください)。途中アバウトダイアログに一部手を入れていますが、実質的には現時点のものでようやくリリース可能レベルという程度と思ってください。
さて、最初のリリースで考えておくべき最後のひと手間は、次のバージョンに向けての最低限の準備となります。それは何かと言うと、より新しいバージョンがいた場合、動作しないようにすることと、新しいバージョンが古いバージョンを検出できるようにするということです。バージョンアップの具体的な手法については、最初のリリースの時点では想定することができませんので、どのような更新形態(3種類のうちどれを選ぶのか)であっても、対応できるように下準備しておきます。少なくともより新しいバージョンがインストールされている場合は、古いバージョンはインストールできないようにするという程度の対応は必要と言えます。そのために必要となる作業は、UpgradeCodeの設定と、より新しいバージョンが検出されたらインストーラを続行しないようにすることの2点です。下記の抜粋ソースがこれに対応したものです。
<Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi"> <?define ProductName = "適すとえでぃた" ?> <?define ProductVersion = "1.01.0000" ?> <?define ProductCode = "{9F7E5565-F367-4735-91E6-66BD76D47C53}" ?> <?define UpgradeCode = "{2B66B2F4-62AB-44e4-B84B-EEA6E185C034}" ?> <Product Id="$(var.ProductCode)" UpgradeCode="$(var.UpgradeCode)" Name="$(var.ProductName)" ...省略...> <!-- 省略 --> <!-- 新しいバージョンを見つけた時のエラーメッセージ --> <CustomAction Id="DetectNewVer" Error="より新しいバージョンが既にインストール されているためインストールできません。"/> <InstallUISequence> <Custom Action="DetectNewVer" After="FindRelatedProducts"> NEWPRODUCTFOUND AND NOT Installed</Custom> </InstallUISequence> <InstallExecuteSequence> <!-- 省略 --> <Custom Action="DetectNewVer" After="FindRelatedProducts"> NEWPRODUCTFOUND AND NOT Installed</Custom> <!-- アップグレード不要を明言。ワーニングが出てしまうが、 これは意図しない削除を行っていないか?の注意喚起のためあえて ワーニングを甘んじて受ける必要がある --> <RemoveExistingProducts Suppress="yes"/> </InstallExecuteSequence> <!-- 将来のバージョンアップへの備え --> <Upgrade Id="$(var.UpgradeCode)"> <UpgradeVersion Minimum="$(var.ProductVersion)" Property="NEWPRODUCTFOUND" OnlyDetect="yes" IncludeMinimum="yes" /> <Property Id="NEWPRODUCTFOUND" Secure="yes" /> </Upgrade> </Product> </Wix>
注意すべき点としては、Product要素に新たにUpgradeCodeを追加している点と、その値と同じものをアップグレード情報として登録している点です。Upgrade要素のIdと自らのUpgradeCodeは必ずしも一致していなければならないわけではありませんが、少なくとも、自身の同系列については(特にメジャーアップグレードする製品については)、一致させることをお勧めします。また、同じ値を複数か所で利用することになりますので、修正ミスを防ぐためにも、サンプルのように、外部定義しておく方が良いでしょう。
これで初回リリースまでに最低限必要となるインストーラの設定は完了です。この後は、動作確認と本当の意味でのリリースとなります。ここでビルドしたものは、以後何かのサポートやパッチ作成(連載では扱っていませんが)などで必要になりますので、必ず保存しておいてください。たとえ、自分のマシンがある日突然クラッシュしてしまっても、なくならないようにしておかなければなりません。