アップデート計画
この連載自体、初級~中級という割には若干敷居が高いかな? と思う部分もあるのですが、一応は入門と銘打ってますので、アップデートもできるだけ簡単に用意できるものを選択したいと思います。期待していた方には申し訳ありませんが、この連載ではパッチ作成については取り扱いません。
古いバージョンをどうするか?
バージョンアップで最初に考えておく必要があるのは、新バージョンがインストールされた際、旧バージョンはどうするのか? です。実際には、下記の3つのパターンのどれかになります。
- 古いバージョンを削除
- 古いバージョンと同居
- ユーザーの選択で上記のどちらかを選択
このうち、メジャーアップグレードに当たるのは、1番になります。同居(選択式はどちらを選んだかで、メジャーアップグレードとなるか、同居となります)は、結果的には別製品として扱うことになりますので、言及するまでもなく、その開発スタイル自体が変わってきます(同居を前提とした開発は、非常に敷居が高く、維持するためにかかる労力は一般的なアプリケーション開発と同じくらいかかります)ので、連載では割愛します。
アップデート版作成時の注意事項
今回はアップデート版となりますので、上記の1に当たる、上書きインストール(旧バージョンを削除)を行うメジャーアップグレードを行うインストーラを作成したいと思います。メジャーアップグレードの動作は、他のアップデート形式とは異なり、ひとことでいえば、旧バージョンをアンインストールして、新バージョンをインストールする(どちらを先に行ってもよい)というものになります。具体的な動作は
- インストール作業開始直前に旧バージョンをアンインストールする
- インストール作業完了直後に旧バージョンをアンインストールする
- インストール作業中に旧バージョンをアンインストールしつつ新バージョンをインストールする
のように3種類に分かれます。1、2は、実際には手作業で先にアンインストールする、あるいは後からアンインストールするということを機械的に行うこととほとんど同じです(もちろん、タイミングが異なるため、動作自体がまったく一緒になるわけではありません)。それに対し、3番だけはまったく動作が異なり、実行時にアンインストールしつつ、インストールも行うという特殊な形態をとります。また、1、2番は後から動く方(1番なら新バージョンのインストール、2番なら旧バージョンのアンインストール)が、何らかの理由で失敗あるいは、キャンセルされたという場合、以前の状態に戻るということがなく、両方いなくなってしまう(単にアンインストールした場合と同じ)あるいは、両方とも残ったままとなる(同居インストールと同じ)状態になってしまいます。
1番なら、旧バージョンが消えるだけで、最悪もう一度古いものをインストールすることで元の状況に戻ることはできますが、残念ながら、後からアンインストールという場合、そこでの失敗は大抵の場合、アンインストールがうまくいかなくなってしまうバグを誘発することになります。
こういった場合、MsiZip(PlatformSDKに同梱)などを利用して、無理やりインストール情報を削除することになるのですが、最悪の事態では、それでもなお対処することができず、OSごと再フォーマットを余儀なくされるということも起こりえます。そのため、基本的なメジャーアップグレードでは、3番の形態をとるのですが、この場合、今度はコンポーネントが同じものなのか変わっているのかでその処置が大分違ってきます。
メジャーアップグレード形態をとる多くの製品では、この3番の形式のインストーラにしておき、旧バージョンと新バージョンで同じフォルダへインストール、かつ旧バージョンからは純粋に更新される部分については今までと同じ形のままにすることで、これらの不整合が発生する可能性そのものをカットアウトするという手法をとっているものが多いようです(そのため、製品によっては更新ではインストール先すら変更できなものもあります)。ただし、この動作自体がオプションのため、必ずしも同じインストール先にしなければならないわけではありません。
アップデート版の作成
一番手軽なアップグレードバージョンの作成方法としては、まずは、wxsのコピーを行います。もちろん、1つのファイルを条件コンパイルで複数に切り替えて使うという方法もありますが、バージョンアップ前と、バージョンアップ後で変わる内容を、1つのファイルで管理していくには限界があります。
また新バージョンと旧バージョンで大きく変わる部分なども出てくることがありますので、やはり別ファイルとしてきちんとバージョン管理していく方が良いでしょう。ファイル名については、こうでなければという決まりはありませんが、可能なら、新旧で違いがすぐに分かるようにファイル名にメジャーバージョンを入れておくなどしておくとよいでしょう。
サンプルでは、同じ場所に配置していますが、これは別に必須というわけではありません。たまたま利用するカスタムアクションに変更がないというだけです。通常大きな製品であれば、カスタムアクションとインストーラデータファイルは同一での管理は行いません。カスタムアクションの方が寿命が長くなることが多いため、カスタムアクションのソリューションはそれだけで独立して管理するほうが、結果的に楽ができます。このあたりは、実際の開発スタイルに合わせて設定していけばよいと思いますが、どういう場合でも必ずリリースしたバージョン当時のソースは残しておくことをお勧めします。
旧バージョンからの変更点
最初の表のうち、メジャーアップグレードで変更しないのはUpgradeCodeだけです。それ以外は基本的に変わる(もしくは変えてもよい)ことになります。前述したサンプルソースの抜粋からもお分かりと思いますが、変更箇所になる部分を外に出して取りまとめています。第5回からの変更点としては、カスタムアクションの動作をさらに小分けにして、DLLの読み込みが必要最小限の部分だけで行われるようにもしています。また、新バージョンへの更新で、対象が増えることを想定し、以前の情報を吸い取ったうえで、新しい設定を行っていることを分かりやすくするためにサンプルテキストデータとしてサンプル3を追加しています。
動作確認
毎度の締めです。まずは動作確認です(インストーラは、システム内部の奥深くにまで影響範囲が広がるため、変更したら必ず動作確認を行ってください)。古いバージョンからのアップグレードを実行してみる場合は、ぜひカスタムアクションでいろいろと試してみてください。何がどう変わるのかよく分かると思います。また、新しいバージョンがインストールされている場合に、後から古いバージョンをインストールしようとした場合にもどうなるのか確認してください。
WiXの要素について
それでは最後に、今回新たに出てきたWiXのデータについて説明します。以下はXML要素の簡単な説明なので、詳細はWiXのサイトの解説(英語)を参照してください。
Upgrade要素
属性名 | 説明 | 必須 |
Id | FindRelatedProductsアクションで検出する対象となるアップグレードコードを指定。 | ○ |
- 参照URL:「Upgrade Element」
UpgradeVersion要素
属性名 | 説明 | 必須 |
Property | FindRelatedProductsで検出された製品のProductCodeを格納するプロパティ。複数の製品が検出された場合、;で区切られて格納される。 | - |
Minimum | 検索対象となる最小バージョン。指定しない場合バージョンは考慮しない。 | - |
IncludeMinimum | Minimumで指定した値のバージョンを含むか否か。 | - |
Maximum | 検索対象となる最大バージョン。指定しない場合バージョンは考慮しない。 | - |
IncludeMaximum | Maximumで指定した値のバージョンを含むか否か。 | - |
OnlyDetect | 検出のみとするか。yesではない場合(省略時はnoとなる)は、アップグレード対象製品として扱われる。 | - |
MigrateFeatures | 以前のインストール情報を踏襲するか。yesではない場合(省略時はnoとなる)は、インストーラ作成時のデフォルト設定になる。 | - |
- 参照URL:「Upgrade Element」
終わりに
今回でこの連載も終わりです。連載ペースも月に1度程度とかなりのんびりであり、入門ということで基礎的な部分しか紹介できていないのですが、いかがだったでしょうか?
WiXの機能としては本当にごくわずかしか紹介できていないのですが、とっかかりとして役に立つことができればと思います。
最後までお読みいただきありがとうございました。