How To: インストーラー中に メジャー アップグレードを実装する

.msi ベースのインストーラーを作成している時、 Windows Installer major upgrades をサポートするロジックを含める事が 強く推奨されます。 メジャー アップグレードは、.msi の為の最も一般的なアップデートの形であり、最初の .msi リリース中で 将来に柔軟性を与えるサポートを含んでいます。 メジャー アップグレードの為のサポートを含める事なしでは、もし のちにアップデートをリリースする 必要があるといつでも、配布を非常に困難にする危険を被ります。

.msi 中でメジャー アップグレードを可能にして、多数のバージョンの .msi をビルド、 メジャー アップグレード シナリオをテストするには、以下のステップを使う事ができます。

ステップ 1: 新しいバージョンに古いバージョンをアップグレードさせるのに必要とされる アップグレード情報を追加する

メジャー アップグレードを許可する為に、.msi 中に以下の情報を含めなければなりません:

プロダクトがアップグレードされ得ると識別する ユニーク ID を追加する

これを達成するには、 Product エレメント中に UpgradeCode 属性を含めなければなりません。 これは以下の様になります:

<Product Id="*"
         UpgradeCode="PUT-GUID-HERE"
         Name="My Application Name"
         Language="1033"
         Version="1.0.1"
         Manufacturer="My Manufacturer Name"/>

新しい .msi によってアップグレードされるべき 古いバージョンの範囲を定義する

UpgradeVersion エレメントは、3 つの部分のバージョン ナンバーを使います。最小のバージョン 値は通常 1.0.0 にセットされ、最大のバージョン値は通常 現在の .msi のバージョンの 3 つの部分 の値にセットされます。これは以下の様になります:

<Upgrade Id="PUT-GUID-HERE">
    <UpgradeVersion Minimum="1.0.0"
                    IncludeMinimum="yes"
                    Maximum="1.0.1"
                    Property="OLDERVERSIONBEINGUPGRADED" />
</Upgrade>

UpgradeVersion エレメント中で指定されたプロパティの正確な名前は 重要ではありませんが、 それは すべて大文字でなければなりません。

古いバージョンの .msi の削除をスケジュールに入れる

古いバージョンの .msi を削除する RemoveExistingProducts アクションをスケジュールする事ができる場所に関して いくつかの オプションがあります。 オプションを再検討して、あなたのシナリオに最も理にかなったものを 選ぶ必要があります。 RemoveExistingProducts ドキュメンテーション ( 英語 ) 中でオプションの要約を見つける事ができます。 もし InstallInitialize の後にそれをスケジュールするのを選ぶなら、 それは以下の様になります:

<InstallExecuteSequence>
    <RemoveExistingProducts After="InstallInitialize"/>
</InstallExecuteSequence>

もし RemoveExistingProducts アクションをスケジュールしないと、 以下の様なエラーを見るでしょう:

error LGHT0094 : Unresolved reference to symbol 'WixAction:InstallExecuteSequence/RemoveExistingProducts' in section 'Product:*'.

Windows Installer は FindRelatedProducts アクションの間、同じ UpgradeCode 値で他にインストールされた .msi ファイルを捜します。 もしセットアップ オーサリング中で FindRelatedProducts アクションを明確にスケジュールしないと、WiX は .msi を作成する時に 自動的にそれをスケジュールします。

ステップ 2: 順番が狂ったインストールを処理する ロジックを追加する(バージョン 2 をインストールしていて その後 バージョン 1 をインストールしようとする事)

ステップ 1 で与えられた情報は、新しいバージョンのインストール プロセスの間 あなたの .msi に 古いバージョンの .msi のアンインストールを可能にします。 完全である為に、ユーザーが新しいバージョンの .msi をインストールして その後に古いバージョンを 後からインストール(順番の狂ったインストール)しようとする場合のシナリオを処理する情報も .msi 中に含めるべきです。 このセットアップは 厳密には必須ではありませんが、.msi 中にこの情報を含める事は 順番の狂った インストール シナリオの場合に よりユーザー フレンドリーなエクスペリエンスを提供する事を 可能 にします。

順番の狂ったインストールを検出する事は、もし より新しいバージョンの .msi がユーザーのシステム上で 見つかったらセットされる プロパティを定義する UpgradeVersion エレメントをオーサリングする事を必要とします。 これは以下の様になります:

<Upgrade Id="PUT-GUID-HERE">
    <UpgradeVersion Minimum="1.0.1"
                    OnlyDetect="yes"
                    Property="NEWERVERSIONDETECTED" />
</Upgrade>

いったん検出プロパティを定義してしまったら、順番の狂ったインストール シナリオで .msi に どのように振る舞わせたいかを決めて、適切なカスタム アクションを書く必要があります。 2 つのオプションがあります:

オプション 1: インストールをブロックする

もしバージョン検出プロパティがセットされると実行する 起動条件を追加する事によって、 インストールをブロックする事ができます。これは以下の様になります:

<Condition Message="A later version of [ProductName] is already installed. Setup will now exit.">
  NOT NEWERVERSIONDETECTED OR Installed
</Condition>

オプション 2: すぐに終了して 成功を返す

これは、終了コード 5(ERROR_NO_MORE_ITEMS)を返すカスタム アクションを作成する必要があります。 WiX は、この機能性を可能にするのに使用され得る WixExitEarlyWithSuccess と呼ばれるビルトイン カスタム アクションを持っています。 ビルトイン カスタム アクションを使用するには、上で作成されたプロパティが NEWERVERSIONDETECTED と名付けられている事を確かにしなければなりません。 その後、以下を追加する事によって セットアップ オーサリングにカスタム アクションを参照しなければ なりません:

<CustomActionRef Id="WixExitEarlyWithSuccess"/>

WixExitEarlyWithSuccess カスタム アクションを使用するには、もし Votive and Visual Studio を使っているなら プロジェクトの為の参照リストに 追加する事に よってか、 light.exe に -ext コマンドライン スイッチで渡す事によってのどちらかで、 WixUtilExtension も参照しなければなりません。

アプリケーションを呼ぶ為の後方互換性をサポートする為に、.msi は 順番の狂ったインストール シナリオで、ブロックしてエラーを返す代わりに すぐに終了して成功を返したいかも しれません。 これは、.msi が他のプロダクトの一部として出荷されてインストールされ得る 再配布可能な コンポーネントである場合に 特に役に立ちます。

ステップ 3: バージョン 1 とバージョン 2 の .msi をビルドする

バージョン 1 の .msi を作成する事は、スタンダード ビルド プロセスを実行する事 - これは WiX toolset でコンパイルとリンクする事を意味しています - と同様に簡単です。 バージョン 2 の .msi を作成する為に、セットアップ オーサリングに以下の変更を行って、 その後 新しい .msi を作成するのにビルド プロセスを再実行しなければなりません:

ステップ 4: バージョン 1 を出荷する前に アップグレード シナリオをテストする

このステップは非常に重要で、大変よく無視されます。 アップグレード シナリオが期待した通りに振る舞う事を確実にする為に、最初のバージョンの .msi を出荷する前に アップグレードをテストすべきです。 バージョン 2 か より高いバージョンの .msi で純粋に修正を作る事によって 修正され得る アップグレードに関連した いくつかのバグがありますが、バージョン 1 を出荷する前に修正されなければ ならない バージョン 1 のアンインストールに影響を及ぼす いくつかのバグがあります。 いったんバージョン 1 が出荷されると、Windows Installer はバージョン 2 インストールの背後で バージョン 1 のアンインストールを行うので メジャー アップグレード シナリオに影響を及ぼし、 バージョン 1 で出荷したアンインストール動作に本質的に固定されます。

ここに、テストする興味を起こさせる いくつかのシナリオがあります:

メジャー アップグレード シナリオをテストしている時、メジャー アップグレード アンインストール の間 カスタム アクションを実行して プロダクトを部分的にインストールされた状態のままにする 事によって起こされる問題に陥るかもしれないので、.msi 中のカスタム アクションにおける条件に 特に注意を払う事を確実にする。 UPGRADINGPRODUCTCODE property は、 RemoveExistingProducts アクションによって起動されるアンインストールの間 アクションを 実行するのを妨げるのに有用であり得ます。

さらに加えて、GAC や Win32 WinSxS store にインストールされる必要がある アセンブリに注意を 払って下さい。 この Knowledge Base アーティクル に、 いくつかのメジャー アップグレードの間 GAC や Win32 WinSxS store からアセンブリを削除できる イベントのシーケンスについてのいくらかの情報が あります。