DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

セットアッププロジェクトによるアップデート

注意:セットアッププロジェクトはVisual Studio 2012からサポートされなくなりました。

ここでは、Visual Studioのセットアッププロジェクト(デプロイメントプロジェクト)で作成するMSIファイルで、アプリケーションのアップデートインストールができるようにする方法を説明します。

まずは、Windows Installerで定義されている3つのアップデートのタイプから説明します。

アップデートの3つのタイプ

Windows Installerでは、アップデートのタイプを、Small Update、Minor Upgrade、Major Upgradeの3つに分類しています。それぞれのタイプに関して詳しくは、「Platform SDK: Windows Installer」の「Patching and Upgrades」で説明されています。

これらのタイプの違いは、Package Code、Product Version、Product Codeを変えるか変えないかという点にあります。以下にその違いを表で示します。

タイプ Package Code Product Version Product Code
Small Update 変更する 変更しない 変更しない
Minor Upgrade 変更する 変更する 変更しない
Major Upgrade 変更する 変更する 変更する

Package Codesは、MSIファイルをアップデートする時に必ず変更する必要があります。Visual StudioではMSIファイルを作成するたびにPackage Codeを変更しますので、通常は気にする必要はありません。

補足:Package Codeを確認、変更するには、エクスプローラでMSIファイルのプロパティを表示し、「概要」ページの「改訂番号」を見るか、Orcaのメニューの「View」-「Summary Information」を使います。

Product Versionは、Minor UpgradeとMajor Upgradeで変更します。Product VersionはVisual Studioでは、Version プロパティで指定します。

Product Codeは、Major Upgradeでのみ変更します。Visual Studioでは、ProductCode プロパティで指定します。

Product Codeを変更すると、前のバージョンのパッケージとは別の製品として扱われるため、前のバージョンが既にインストールされていたとしても、インストールすることができます。これに対してProduct Codeを変更しなかった時は同じ製品として扱われるため、前のバージョンがインストールされていると、「別のバージョンの製品がすでにインストールされています」メッセージが表示され(注)、前のバージョンをアンインストールしないと新しいバージョンをインストールすることができません。

注:Package Code、Product Version、Product Codeのすべてを変更しなかった時は、「アプリケーションの修正または削除」ダイアログが表示されます。
補足:Major Upgradeで新しいバージョンがインストールされているときに古いバージョンをインストールできないようにする方法や、古いバージョンをアンインストールしてから新しいバージョンをインストールする方法に関しては、後述します。

どのアップデートを選択するか

どのような状況でどのタイプのアップデートを行うべきかについては、「Patching and Upgrades」等で説明されています。簡単に説明すると、次のようになります。

まず、別の製品として扱えるアップデートを行うには、Major Upgradeとします。また、アップデート前のバージョンと、アップデート後のバージョンを区別する必要があるならばMinor Upgrade、そうでなければSmall Updateとします。一般的に言われるquick fix engineering(QFE)がSmall Updateに、service pack(SP)がMinor Upgradeに相当します。

これ以外にも、いくつかのガイドラインがあります。これに関しては、以下のリンク先で説明されています。

この内、Visual Studioを使用してMSIファイルを作成する際に問題となりそうな箇所を以下に列挙します。(英語の解読に自信がないため、正確でない点があるかもしれません。)

  • Small Update、Minor Upgradeでは、MSIファイルの名前を変えてはいけない。ファイル名を変えるならば、Major Upgradeとする。
  • バージョンのあるファイルが修正された場合、バージョンは増加していなければならない。(Visual Studioでは、ファイルのバージョンをFileテーブルに書き込んでいるようなので。)
  • Small UpdateはWindows Installerパッチパッケージとして出荷する。
  • 同一システムでアップデート前のアプリケーションと共存できるようにするには、Major Upgradeとする。
  • ファイルやレジストリキーが削除されるならば、Major Upgradeとする。(Visual Studioでは、ファイルやレジストリキーをそれぞれ一つのcomponentとして扱っているため。)
  • 新しいファイルやレジストリキーを追加しても、Major Upgradeとしなければならない訳ではない。(.NET Frameworkでは、Windows Installer 2.0以上が必須のため。)

アップデートの実際

いよいよアップデートの具体的な方法についての説明に入ります。Visual StudioではMSIファイルしか作れず、パッチは作れませんので、MSIファイルによるアップデートの方法を考えなければなりません。

MSIファイルによるアップデートに関しては、次のページが参考になります。

補足:「InstallSite: Minor and Major Upgrades Using IPWI」では3つの方法が紹介されていますが、この内1と3がそれぞれ「Applying Small Updates by Reinstalling the Product」と「Applying Major Upgrades by Installing the Product」に相当します。

InstallSite: Minor and Major Upgrades Using IPWI」では3つの方法が紹介されていますが、この内Visual Studioで扱えるのは最後の「3: Major upgrades」だけです。まずはこの方法から紹介します。

Major Upgrade

この方法は、Major Upgradeを行うものです。よって、Product VersionとProduct Codeの両方を変更しなければなりません。Visual StudioでProduct Versionを変更するには、セットアッププロジェクトのVersionプロパティを変更します(注)。

注:Product Versionは「.」で区切られた数字のうち、はじめの3つのみを考慮し、残りは無視しますので、少なくともはじめの3つの数字のいずれかを変更する必要があります。

Visual StudioではVersionプロパティを変更すると、ProductCodeとPackageCodeの変更を勧められます。ここではMajor Upgradeを行うため、「はい」を選択し、Product Codeも変更します。(後でProductCodeプロパティを変更することもできます。)

Visual Studioでは、Major Upgradeを行う際の動作を、DetectNewerInstalledVersionプロパティとRemovePreviousVersionsプロパティで指定することができます。

DetectNewerInstalledVersion プロパティをTrueにすると、現在インストールされているバージョンよりも古いバージョンをインストールすることができなくなります。DetectNewerInstalledVersionプロパティがTrueの時に古いバージョンをインストールしようとすると、インストールの実行前に「このプロダクトの新しいバージョンが既にインストールされているためインストールできません。」というメッセージが表示され、インストールが未完了のまま終了します。

またRemovePreviousVersionsプロパティをTrueにすると、既に古いバージョンがインストールされていたらこれをアンインストールしてから新しいパッケージをインストールするようになります。

前に述べたとおり、Major Upgradeでは別の製品として扱われるため、古いバージョンが既にインストールされていてもそれとは別の製品としてインストールされます。つまりMajor Upgradeは前のバージョンを上書きして(あるいは置き換えて)インストールするということではありません。前のバージョンと同じフォルダにインストールすれば、ファイルを上書きすることはできますが、コントロールパネルの「プログラムの追加と削除」には古いバージョンが残されたまま、新しいバージョンの項目が追加されます。つまり、新しいバージョンを古いバージョンに置き換える場合は、古いバージョンをアンインストールしてから新しいバージョンをインストールしなければなりません。それを自動的に行うようにするのが、RemovePreviousVersions プロパティです。

なおこのようなMajor UpgradeではUpgradeCodeが使われるため、UpgradeCodeは絶対に変えてはいけません。

このようにVisual Studioでアップデートを行うMSIファイルを作成する時はMajor Upgradeとし、DetectNewerInstalledVersionとRemovePreviousVersionsプロパティをTrueにするというやり方が基本となります。

注意:RemovePreviousVersionsプロパティをTrueにしても前のバージョンがアンインストールされないケースが幾つかあります。例えば、Versionプロパティが1.0.0以下の製品が既にインストールされていたとしてもアンインストールしません(これはVisual StudioがUpgradeテーブルのVersionMin列を「1.0.0.0」としているためです)。また、前のバージョンのインストールが「このユーザーのみ」で、新しいバージョンを「すべてのユーザー」としてインストールする時(逆も同じ)もそうです。これらに関して、以下のページで幾つか紹介されています。 後者の問題は、常に「すべてのユーザー」でインストールされるようにすることにより解決できます。そのためには、「「すべてのユーザー」がデフォルトになるようにする」と「「すべてのユーザー/このユーザーのみ」チェックボックスを隠す」を参考にしてください。
注意:RemovePreviousVersionsプロパティをTrueとして、Installerクラスを使ったカスタムアクションをインストール時とアンインストール時に使用している場合、新しいバージョンのインストールで古いバージョンのInstallメソッドが呼び出されるというバグがあります。詳しくは、以下のURL先をご覧ください。
注意:Visual Studio .NET 2002では、はじめのインストールで「すべてのユーザー」とした場合、アップデートでRemovePreviousVersionsプロパティが機能しないようです。これを修正するには、OrcaでInstallUISequenceテーブルのFindRelatedProductsのSequenceがWelcomeFormの後になるようにします。詳しくは、次のリンク先をご覧ください。
補足:DetectNewerInstalledVersionとRemovePreviousVersionsプロパティはUpgradeテーブルを使用するための設定です。DetectNewerInstalledVersionのAttributesはmsidbUpgradeAttributesVersionMinInclusive+msidbUpgradeAttributesOnlyDetect、RemovePreviousVersionsのAttributesはmsidbUpgradeAttributesVersionMinInclusiveとなります。詳しくは、「Platform SDK」の「Upgrade Table」をご覧ください。

再インストール

InstallSite: Minor and Major Upgrades Using IPWI」の「1: Upgrading by reinstalling」では、再インストールによる方法が紹介されています。この方法はProduct Codeを変更しないアップグレードでのみ可能です。残念ながらVisual Studioだけではできません(最後の「補足」で紹介するようなツールを使えば、可能です)。

この方法では、MSIファイルの再インストールを

msiexec /i Setup1.msi REINSTALLMODE=voums REINSTALL=ALL

のようなコマンドラインで実行します。なお、既にあるファイルを置き換えるか、レジストリキーを書き換えるかの指定は、REINSTALLMODEで行います。(Windows Installerプロパティを設定する方法の詳細は、こちらをご覧ください。)

これでこのパッケージが再インストールされるわけですが、問題ははじめてのインストールの時には何もインストールされないということです。よって、初めてのインストールであるか判断して、プロパティを適当に変更しなければなりません。

この対処法もInstallSiteで説明されていますが、これにはOrcaが必要です。

まずCustomActionテーブルに次のような行を追加します。

Action Type Source Target
fix_reinstall 51 REINSTALL {}

また、InstallExecuteSequenceとInstallUISequenceテーブルに次のような行を追加します。(Sequence列はCostFinalizeの前になるように調節してください。)

Action Condition Sequence
fix_reinstall NOT Installed 999

以上のようにすることにより、既に同じProductCodeの製品がインストールされている時は、REINSTALLプロパティが削除されるようになります。これで、初めてインストールする時も正常にインストールされるようになります。

補足:上記のようにMSIファイルのデータベースをいじる方法以外に、Bootstrapperを使って既に同じProductCodeの製品がインストールされているかを調べ、コマンドラインを変更する方法もあります。これを可能にするBootstrapperとしては、「VSSetup」があります。

MsiExecでアンインストールする

InstallSite: Minor and Major Upgrades Using IPWI」の「2: Upgrading by launching MsiExec」では、MsiExecにより指定したProductCodeの製品をアンインストールしてから新たなパッケージをインストールする方法が紹介されています。これもVisual Studioだけではできませんが、先に紹介したRemovePreviousVersionsプロパティによる方法のほうが優れていますので、この方法を使う必要はないでしょう。この方法の説明は省略させていただきます。

  • 履歴:
  • 2010/10/29 誤字修正。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • .NET Tipsをご利用いただく際は、注意事項をお守りください。