WiXインストーラーのアップグレードを実装する方法?


233

職場では、インストールパッケージのビルドにWiXを使用しています。製品Xをインストールすると、そのマシンからその製品の以前のバージョンがアンインストールされます。

メジャーアップグレードについてインターネット上のいくつかの場所を読みましたが、機能しませんでした。以前のバージョンのアンインストール機能をWiXに追加するために必要な正確な手順を誰かが指定できますか?

回答:


189

最新バージョン(3.5.1315.0ベータ版)では、独自のバージョンを使用する代わりにMajorUpgrade要素を使用できます。

たとえば、このコードを使用して自動アップグレードを実行します。ダウングレードを防ぎ、ローカライズされたエラーメッセージを表示します。また、既存の同一バージョンのアップグレードを防ぎます(つまり、より低いバージョンのみがアップグレードされます)。

<MajorUpgrade
    AllowDowngrades="no" DowngradeErrorMessage="!(loc.NewerVersionInstalled)"
    AllowSameVersionUpgrades="no"
    />

8
これに関するボブ・アーソンのブログ投稿は、多くの素晴らしい情報を提供します。
Dave Andersen、

17
注:どこにも記載されていませんが、「<MajorUpgrade>」要素はの に配置する必要があります<Package>。それ以外の場合candleは、次のエラーが発生します。「エラーCNDL0107:スキーマ検証が行1、列473の次のエラーで失敗しました:名前空間の要素 'Product' ' schemas.microsoft.com/wix/2006/wi 'に無効な子要素 'がありますMajorUpgrade」内の名前空間『schemas.microsoft.com/wix/2006/wi』。可能な要素のリスト予想: 『パッケージ』 "。。
Rob W

21
+1この回答は、できるだけ多くの賛成票を受け取る必要があります。賛成投票の5倍の回答を使用するのは非常に魅力的ですが、古いアプローチを使用しています。
Lynn Crumbling

1
いい視点ね。例がないので無視されないように例を追加しました!
Ant

6
AllowDowngradesまたはを指定する必要がないことを指摘したいだけですAllowSameVersionUpgrades。デフォルトでは、いいえになっています。
Luminous

221

最後に私は解決策を見つけました-同じ問題を抱えている可能性のある他の人(5人全員)のためにここに投稿しています:

  • 製品IDを*に変更します
  • 製品の下に次を追加します。

    <Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" />
    <Upgrade Id="YOUR_GUID">  
       <UpgradeVersion
          Minimum="1.0.0.0" Maximum="99.0.0.0"
          Property="PREVIOUSVERSIONSINSTALLED"
          IncludeMinimum="yes" IncludeMaximum="no" />
    </Upgrade> 
  • InstallExecuteSequenceの下に以下を追加します。

    <RemoveExistingProducts Before="InstallInitialize" /> 

これからは、製品をインストールするたびに、以前にインストールされたバージョンが削除されていました。

注:アップグレードIDを独自のGUIDに置き換えます


153
はい、WiXの学習は、誰かが「理にかなった」単純なアクションを実行することを決定したあいまいな呪文を理解しようとするようなものです。UNIXのようなものです。
mmr 2009年

6
また、「製品IDを*に変更する」とは正確にはどうなりますか?毎回新しい製品IDを生成しますか?製品に固定IDがなくなるという結果はありますか?-やり過ぎのように聞こえます。
アンソニー

10
@ Antony、@ Dror Helper:ここで新しいGUIDを生成するために "*"を使用するべきではないと確信しています。(Upgrade Id = "")内のGUIDはハードコーディングして修正する必要があり、(Product UpgradeCode = "")属性のGUIDと一致する必要があります。
ジョナサンハートレイ

37
実際のGUIDがないように、ここで例を編集する必要があると思います。人々はそれをコピーして貼り付け、それを逐語的に使用すると確信しています。「YOUR-PRODUCT'S-UPGRADECODE-GUID-HERE」を使用することはできますか?
ブラウン

12
あなたの例にはバグがあります。MSI ProductVersionは3つのバージョンフィールドのみをサポートしています。したがって、4番目のフィールドはまったく比較されません。msdn.microsoft.com/en-us/library/aa372379(VS.85).aspxの
Sridhar Ratnakumar

89

以下は、メジャーアップグレードに使用する一種の構文です。

<Product Id="*" UpgradeCode="PUT-GUID-HERE" Version="$(var.ProductVersion)">
 <Upgrade Id="PUT-GUID-HERE">
    <UpgradeVersion OnlyDetect="yes" Minimum="$(var.ProductVersion)" Property="NEWERVERSIONDETECTED" IncludeMinimum="no" />
    <UpgradeVersion OnlyDetect="no" Maximum="$(var.ProductVersion)" Property="OLDERVERSIONBEINGUPGRADED" IncludeMaximum="no" />
</Upgrade>

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

@Brian Gillespieが指摘したように、必要な最適化に応じて、RemoveExistingProductsをスケジュールする他の場所があります。PUT-GUID-HEREは同一でなければならないことに注意してください。


2
私はここでWixに関するNick Ramirezの本の「アップグレードとパッチ」セクションを読んでおり、InstallInitializeの後にRemoveExistingProductsをスケジュールする場合は、もスケジュールする必要があると述べてい<InstallExecute After="RemoveExistingProducts" />ます。あなたの例にはこれがありません-それは本が間違っていることを意味しますか?
Wim Coenen、2010年

3
InstallExecuteを明示的にスケジュールすることはありません。
Rob Mensching、2010年

1
私はしません。WiX v3.6では、Burnを使用するとマイナーアップグレードを簡単に実行できますが、Burnを使用しない場合は、ユーザーによる手動の操作(コマンドラインオプションを提供する必要があります)が必要になるため、マイナーアップグレードは基本的に役に立たなくなります。:)
Rob Mensching、

1
@RobMensching:新しいバージョンより古いバージョンのインストールをどのように回避しますか?あなたの答えは私には有効ですが(WiX v3.5.2519.0でコンパイルできる唯一の「メジャーアップグレード」の例)、古いバージョンをインストールすることは可能です(その後、「追加/プログラムの削除」)。
Christian Specht、

4
さて、私はこの回答MajorUpgrade要素を見つけました。これは、ダウングレードの防止を含め、私が望んでいることを正確に実行します。
Christian Specht

40

Product要素内のUpgrade要素とアクションの適切なスケジューリングを組み合わせることで、目的のアンインストールが実行されます。削除するすべての製品のアップグレードコードを必ずリストしてください。

<Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" />
<Upgrade Id="00000000-0000-0000-0000-000000000000">
  <UpgradeVersion Minimum="1.0.0.0" Maximum="1.0.5.0" Property="PREVIOUSVERSIONSINSTALLED" IncludeMinimum="yes" IncludeMaximum="no" />
</Upgrade>

ビルドに注意を払えば、新しいバージョンの上に古いバージョンの製品を誤ってインストールするのを防ぐことができます。それが最大フィールドの目的です。インストーラーをビルドするとき、UpgradeVersion Maximumをビルドされるバージョンに設定しますが、IncludeMaximum = "no"はこのシナリオを回避します。

RemoveExistingProductsのスケジュールに関する選択肢があります。私は、InstallFinalizeの後(他の人が推奨しているInstallInitializeの後ではなく)スケジュールすることを好みます。

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

これにより、新しいファイルとレジストリキーがコピーされるまで、製品の以前のバージョンがインストールされたままになります。これにより、古いバージョンから新しいバージョンにデータを移行できます(たとえば、ユーザー設定のストレージをレジストリからXMLファイルに切り替えましたが、その設定を丁寧に移行したいと考えています)。この移行は、InstallFinalizeの直前の遅延カスタムアクションで行われます。

もう1つの利点は効率です。変更されていないファイルがある場合、Windowsインストーラーは、InstallFinalizeの後でスケジュールするときに、それらを再度コピーする手間を省きます。InstallInitializeの後にスケジュールを設定すると、最初に以前のバージョンが完全に削除されてから、新しいバージョンがインストールされます。これにより、ファイルの不要な削除と再コピーが発生します。

その他のスケジュールオプションについては、MSDNのRemoveExistingProductsヘルプトピックを参照してください。今週のリンクは、http//msdn.microsoft.com/en-us/library/aa371197.aspxです


2
@Brian Gillespie:「...変更されていないファイルがある場合...」とはどういう意味ですか?Windowsインストーラーがファイル、AssemblyVersion、AssemblyFileVersion、ファイルサイズなどをいつ置換するかを決定する基準は何ですか?
donttellya 2014年

2
@donttellya +1はこれを難しい方法で学びました。RemoveExistingProducts後にスケジュールInstallFinalizeされ、AssemblyVersionは変更されなかったため、dllは更新されませんでしたが、AssemblyProductなどの他のフィールドは更新されました。私はファイル比較ルーチンのなすがままになりたくありません-私は以前のアプリが消えてほしかった
wal

16

WiX-usersメーリングリストでこれを尋ねた方がよいかもしれません。

WiXは、Windowsインストーラーの動作を十分に理解した上で使用するのが最適です。「Windowsインストーラーの決定的なガイド」を入手することを検討してください。

既存の製品を削除するアクションは、RemoveExistingProductsアクションです。それが行うことの結果は、それがスケジュールされている場所、つまり障害が原因で古い製品が再インストールされるかどうか、および変更されていないファイルが再度コピーされるかどうかに依存するため、自分でスケジュールする必要があります。

RemoveExistingProducts<Upgrade>現在のインストールの要素を処理し、システムにインストールされているすべての製品@IdUpgradeCode<Product>要素で指定されている)に属性を一致させます。UpgradeCode関連する製品ファミリを定義します。このUpgradeCodeがあり、バージョンが指定された範囲内にあり、UpgradeVersion/@OnlyDetect属性がno(または省略されている)製品はすべて削除されます。

プロパティのRemoveExistingProducts設定についてのドキュメントUPGRADINGPRODUCTCODE。これは、削除される製品のアンインストールプロセスそのプロパティを受け取ることを意味します。その値は、Product/@Idインストールされる製品のです。

元のインストールにが含まれていない場合は、UpgradeCodeこの機能を使用できません。


21
Mikeが彼の話していることをきちんと理解していることは間違いありませんが、Windowsインストーラが何をしているのかをしっかりと理解して頭が雑然としていることを考えると、私は絶望にため息をつきます。気が付く前に、私はJavaと.NETのコンサルティングジョブをエンタープライズのクライアントに向けて、途方もないテックセンターの町の環状道路を越えて、TPSレポートを記入し、なぜ人生がそんなに空っぽに見えるのか疑問に思っています。私の次のプロジェクトはNSISでインストールされる可能性があると思います。NSISは、そのすべての欠点のために、途方もないアセンブリのような言語のように、Windowsインストーラーが何をしているのか理解できませんでした。
ジョナサンハートレイ

2
@Tartley-InnoSetupを使用すると、アセンブリのような言語を節約できます:) IStoolも取得できることを確認してください。また、-単純なインストールの場合、これはすべて複雑すぎるが、SQL Server 2008のようなものをインストールする場合は、この複雑さが本当に必要であると同意しました...
Roman Starkov

11

このサイトを使用して、WiXアップグレードの基本を理解しました。

http://wix.tramontana.co.hu/tutorial/upgrades-and-modularization

その後、サンプルインストーラー(テストファイルをインストール)を作成し、アップグレードインストーラー(2つのサンプルテストファイルをインストール)を作成しました。これにより、メカニズムがどのように機能するかについての基本的な理解が得られます。

マイクがApressの本「Windowsインストーラーの決定版ガイド」で言ったように、理解するのに役立ちますが、WiXを使用して書かれていません。

かなり参考になった別のサイトはこれでした:

http://www.wixwiki.com/index.php?title=Main_Page


ページの例は期待どおりに動作しませんwix.tramontana.co.hu/tutorial/upgrades-and-modularization/…。私はそれで遊んだ。禁止されることがページで示されている場合、ダウングレードすることも可能です
sergtk

10

WiXのドキュメントを読み、サンプルをダウンロードしましたが、それでもアップグレードに関して多くの問題がありました。マイナーアップグレードでは、それらのアンインストールを指定する可能性があるにもかかわらず、以前の製品のアンインストールを実行しません。私は調査に1日以上費やし、WiX 3.5がアップグレード用の新しいタグを導入したことを発見しました。使い方は次のとおりです。

<MajorUpgrade Schedule="afterInstallInitialize"
        DowngradeErrorMessage="A later version of [ProductName] is already installed. Setup will now exit." 
        AllowDowngrades="no" />

しかし、問題の主な理由は、ドキュメントがマイナーアップグレードと小規模アップグレードに「REINSTALL = ALL REINSTALLMODE = vomus」パラメーターを使用するように言っていることですが、これらのパラメーターはメジャーアップグレードで禁止されているとは言いません。そのため、メジャーアップグレードでは使用しないでください。



7

しばらくの間チュートリアルから見逃していた重要な点の1つ(http://www.tramontana.co.hu/wix/lesson4.phpから盗まれた)で、「この製品の別のバージョンがすでにインストールされています」というエラーが発生しました。

* 小さな更新と は、製品バージョン(major.minor.build)の変更が保証されない1つまたはいくつかのファイルへの小さな変更を意味します。製品GUIDを変更する必要もありません。以前のファイルとはまったく異なる新しい.msiファイルを作成するときは、常にパッケージGUIDを変更する必要があることに注意してください。インストーラーはインストールされたプログラムを追跡し、ユーザーがこれらのGUIDを使用してインストールを変更または削除する場合にそれらを見つけます。異なるパッケージに同じGUIDを使用すると、インストーラーが混乱します。

マイナーアップグレード は、製品バージョンがすでに変更される変更を示します。製品タグのバージョン属性を変更します。製品は同じままなので、製品GUIDを変更する必要はありませんが、もちろん、新しいパッケージGUIDを取得します。

メジャーアップグレード は、あるフルバージョンから別のフルバージョンへの移行などの重要な変更を示します。すべてを変更します:バージョン属性、製品およびパッケージGUID。


3
Package:Idタイプ:AutogenGuid説明:製品またはマージモジュールのパッケージコードGUID。製品をコンパイルするときは、ビルドごとにパッケージコードを生成できるようにするために、この属性を設定しないでください。マージモジュールをコンパイルするときは、この属性をモジュール化GUIDに設定する必要があります。----パッケージIDに注意を払う必要はありませんよね?
Cooper.Wu、2011年

あなたのリンクは死んでいます
bam500

5

WiXの最新バージョン(3.0)を使用していますが、上記を機能させることができませんでした。しかし、これはうまくいきました:

<Product Id="*" UpgradeCode="PUT-GUID-HERE" ... >

<Upgrade Id="PUT-GUID-HERE">
  <UpgradeVersion OnlyDetect="no" Property="PREVIOUSFOUND"
     Minimum="1.0.0.0"  IncludeMinimum="yes"
     Maximum="99.0.0.0" IncludeMaximum="no" />
</Upgrade>

PUT-GUID-HEREは、製品のUpgradeCodeプロパティで定義したGUIDと同じである必要があります。


2

以下は私のために働きました。

<Product Id="*" Name="XXXInstaller" Language="1033" Version="1.0.0.0" 
    Manufacturer="XXXX" UpgradeCode="YOUR_GUID_HERE">
<Package InstallerVersion="xxx" Compressed="yes"/>
<Upgrade Id="YOUR_GUID_HERE">
    <UpgradeVersion Property="REMOVINGTHEOLDVERSION" Minimum="1.0.0.0" 
        RemoveFeatures="ALL" />
</Upgrade>
<InstallExecuteSequence>
    <RemoveExistingProducts After="InstallInitialize" />
</InstallExecuteSequence>

製品のUpgradeCodeがアップグレードのIDと一致していることを確認してください。


1

メジャーダウングレードでも、これは私にとってうまくいきました

<Wix ...>
  <Product ...>
    <Property Id="REINSTALLMODE" Value="amus" />
    <MajorUpgrade AllowDowngrades="yes" />
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.