Wie implementiere ich ein Upgrade des WiX-Installationsprogramms?

233

Bei der Arbeit verwenden wir WiX zum Erstellen von Installationspaketen. Wir möchten, dass die Installation von Produkt X zur Deinstallation der vorherigen Version dieses Produkts auf diesem Computer führt.

Ich habe an mehreren Stellen im Internet über ein größeres Upgrade gelesen, konnte es aber nicht zum Laufen bringen. Kann jemand bitte die genauen Schritte angeben, die ich ausführen muss, um WiX die Funktion zur Deinstallation früherer Versionen hinzuzufügen?

Dror Helfer
quelle

Antworten:

189

In den neuesten Versionen (ab der Beta-Version 3.5.1315.0) können Sie das MajorUpgrade-Element anstelle Ihres eigenen verwenden.

Zum Beispiel verwenden wir diesen Code, um automatische Upgrades durchzuführen. Es verhindert Downgrades, gibt eine lokalisierte Fehlermeldung aus und verhindert auch das Upgrade einer bereits vorhandenen identischen Version (dh nur niedrigere Versionen werden aktualisiert):

<MajorUpgrade
    AllowDowngrades="no" DowngradeErrorMessage="!(loc.NewerVersionInstalled)"
    AllowSameVersionUpgrades="no"
    />
Ameise
quelle
8
Bob Arnsons Blog-Post darüber bietet viele nette Informationen.
Dave Andersen
17
Hinweis: Nicht überall dokumentiert, aber das „ <MajorUpgrade>“ Element muss gestellt werden , nachdem <Package> . Andernfalls wird candleder folgende Fehler ausgegeben: "Fehler CNDL0107: Die Schemaüberprüfung ist mit dem folgenden Fehler in Zeile 1, Spalte 473 fehlgeschlagen: Das Element 'Produkt' im Namespace ' schemas.microsoft.com/wix/2006/wi ' hat ein ungültiges untergeordnetes Element. ' MajorUpgrade 'im Namespace' schemas.microsoft.com/wix/2006/wi '. Liste der möglichen erwarteten Elemente:' Package '. "
Rob W
21
+1 Diese Antwort muss so viele positive Stimmen wie möglich erhalten. Es ist sehr verlockend, eine Antwort zu wählen, die das Fünffache der positiven Stimmen hat, aber ältere Ansätze verwendet.
Lynn Crumbling
1
Guter Punkt. Ich habe ein Beispiel hinzugefügt, damit die Leute es nicht ignorieren, nur weil es keines hat!
Ameise
6
Ich möchte nur darauf hinweisen, dass Sie nicht angeben müssen AllowDowngradesoder AllowSameVersionUpgrades. Sie sind standardmäßig bereits nein.
Leuchtend
221

Endlich habe ich eine Lösung gefunden - ich poste sie hier für andere Leute, die möglicherweise das gleiche Problem haben (alle 5 von Ihnen):

  • Ändern Sie die Produkt-ID in *
  • Fügen Sie unter Produkt Folgendes hinzu:

    <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> 
  • Fügen Sie unter InstallExecuteSequence Folgendes hinzu:

    <RemoveExistingProducts Before="InstallInitialize" /> 

Von nun an wurden bei jeder Installation des Produkts frühere installierte Versionen entfernt.

Hinweis: Ersetzen Sie die Upgrade-ID durch Ihre eigene GUID

Dror Helfer
quelle
153
Ja, das Erlernen von WiX ist wie der Versuch, die obskuren Beschwörungsformeln herauszufinden, die jemand für sinnvoll hielt, um eine einfache Aktion auszuführen. Ein bisschen wie UNIX.
mmr
6
Was genau bewirkt "Produkt-ID in * ändern"? Generiert es jedes Mal eine neue Produkt-ID? Gibt es Konsequenzen für Ihr Produkt, das keine feste ID mehr hat? - Es klingt wie Overkill.
Anthony
10
@Antony, @Dror Helper: Ich bin mir ziemlich sicher, dass Sie hier nicht "*" verwenden sollten, um eine neue GUID zu generieren. Die darin enthaltene GUID (Upgrade Id = "") sollte fest codiert und festgelegt sein und mit der GUID in Ihrem Attribut (Product UpgradeCode = "") übereinstimmen.
Jonathan Hartley
37
Ich denke, Sie sollten Ihr Beispiel dort wahrscheinlich bearbeiten, um KEINE tatsächliche GUID zu haben. Ich bin sicher, die Leute werden das kopieren und einfügen und es wörtlich verwenden. Vielleicht verwenden Sie "YOUR-PRODUCT'S-UPGRADECODE-GUID-HERE"?
Brown
12
Ihr Beispiel enthält einen Fehler. MSIs unterstützen ProductVersionnur drei Versionsfelder. Daher wird das vierte Feld überhaupt nicht verglichen. Siehe den Hinweis unter VersionMin und VersionMax in msdn.microsoft.com/en-us/library/aa372379(VS.85).aspx
Sridhar Ratnakumar
89

Die folgende Syntax verwende ich für größere Upgrades:

<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>

Wie @Brian Gillespie feststellte, gibt es andere Orte, an denen die RemoveExistingProducts abhängig von den gewünschten Optimierungen geplant werden können. Beachten Sie, dass die PUT-GUID-HERE identisch sein muss.

Rob Mensching
quelle
2
Ich lese hier den Abschnitt "Aktualisieren und Patchen" in Nick Ramirez 'Buch über Wix und er gibt an, dass Sie, wenn Sie RemoveExistingProducts nach InstallInitialize planen, auch planen müssen <InstallExecute After="RemoveExistingProducts" />. Ihr Beispiel hat dies nicht - bedeutet das, dass das Buch falsch ist?
Wim Coenen
3
Ich plane InstallExecute nie explizit.
Rob Mensching
1
Ich nicht. In WiX v3.6 macht Burn kleinere Upgrades einfach auszuführen, aber ohne Burn erfordert es eine manuelle Interaktion des Benutzers (muss Befehlszeilenoptionen bereitstellen), die kleinere Upgrades grundsätzlich unbrauchbar macht. :)
Rob Mensching
1
@RobMensching: Wie vermeidet man die Installation einer älteren Version gegenüber einer neueren? Ihre Antwort funktioniert für mich (das einzige "Haupt-Upgrade" -Beispiel, das ich mit WiX v3.5.2519.0 überhaupt kompilieren kann), aber es ist möglich, eine ältere Version zu installieren (danach werden beide Versionen unter "Hinzufügen /" angezeigt) Programme entfernen ").
Christian Specht
4
Okay, ich habe gerade das MajorUpgrade-Element in dieser Antwort gefunden, das genau das tut, was ich will, einschließlich der Verhinderung von Downgrades.
Christian Specht
40

Das Upgrade-Element im Product-Element führt in Kombination mit der richtigen Planung der Aktion die Deinstallation durch, nach der Sie suchen. Stellen Sie sicher, dass Sie die Upgrade-Codes aller Produkte auflisten, die Sie entfernen möchten.

<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>

Beachten Sie, dass Sie, wenn Sie mit Ihren Builds vorsichtig sind, verhindern können, dass Personen versehentlich eine ältere Version Ihres Produkts über eine neuere installieren. Dafür ist das Feld Maximum gedacht. Wenn wir Installationsprogramme erstellen, setzen wir UpgradeVersion Maximum auf die zu erstellende Version, aber IncludeMaximum = "no", um dieses Szenario zu verhindern.

Sie haben die Wahl zwischen der Planung von RemoveExistingProducts. Ich bevorzuge es nach InstallFinalize zu planen (anstatt nach InstallInitialize, wie andere empfohlen haben):

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

Dadurch bleibt die vorherige Version des Produkts installiert, bis die neuen Dateien und Registrierungsschlüssel kopiert wurden. Auf diese Weise kann ich Daten von der alten auf die neue Version migrieren (Sie haben beispielsweise die Speicherung von Benutzereinstellungen aus der Registrierung in eine XML-Datei umgestellt, möchten jedoch höflich sein und deren Einstellungen migrieren). Diese Migration wird in einer verzögerten benutzerdefinierten Aktion unmittelbar vor InstallFinalize durchgeführt.

Ein weiterer Vorteil ist die Effizienz: Wenn Dateien unverändert vorhanden sind, kopiert Windows Installer sie nicht erneut, wenn Sie nach InstallFinalize planen. Wenn Sie nach InstallInitialize planen, wird zuerst die vorherige Version vollständig entfernt und dann die neue Version installiert. Dies führt zu unnötigem Löschen und erneuten Kopieren von Dateien.

Weitere Planungsoptionen finden Sie im Hilfethema RemoveExistingProducts in MSDN. Diese Woche lautet der Link: http://msdn.microsoft.com/en-us/library/aa371197.aspx

Brian Gillespie
quelle
2
@ Brian Gillespie: Was bedeutet "... wenn es unveränderte Dateien gibt ..."? Nach welchen Kriterien kann Windows Installer entscheiden, wann eine Datei, AssemblyVersion, AssemblyFileVersion, Dateigröße usw. ersetzt werden soll?
Donttellya
2
@donttellya +1 hat das auf die harte Tour gelernt. RemoveExistingProductswurde nachher geplant InstallFinalizeund DLLs wurden nicht aktualisiert, da AssemblyVersion unverändert blieb, andere Felder wie AssemblyProduct jedoch. Ich habe nicht auf Gedeih und Verderb der Datei Vergleichsroutine sein wollen - ich will nur die vorherige App GONE
wal
16

Fragen Sie dies möglicherweise besser in der Mailingliste der WiX-Benutzer .

WiX wird am besten verwendet, wenn Sie genau wissen, was Windows Installer tut. Möglicherweise möchten Sie " The Definitive Guide to Windows Installer " herunterladen .

Die Aktion, mit der ein vorhandenes Produkt entfernt wird, ist die Aktion RemoveExistingProducts . Da die Konsequenzen dessen, was es tut, davon abhängen, wo es geplant ist - nämlich ob ein Fehler dazu führt, dass das alte Produkt neu installiert wird und ob unveränderte Dateien erneut kopiert werden - müssen Sie es selbst planen.

RemoveExistingProductsverarbeitet <Upgrade>Elemente in der aktuellen Installation und @Idordnet das Attribut dem UpgradeCode(im <Product>Element angegebenen) aller auf dem System installierten Produkte zu. Das UpgradeCodedefiniert eine Familie verwandter Produkte. Alle Produkte mit diesem UpgradeCode, deren Versionen in den angegebenen Bereich fallen und in denen das UpgradeVersion/@OnlyDetectAttribut vorhanden ist no(oder weggelassen wird), werden entfernt.

Die Dokumentation für RemoveExistingProductsErwähnungen zum Festlegen der UPGRADINGPRODUCTCODEEigenschaft. Dies bedeutet, dass der Deinstallationsprozess für das zu entfernende Produkt diese Eigenschaft erhält, deren Wert der Product/@Idfür das zu installierende Produkt ist.

Wenn Ihre ursprüngliche Installation keine enthielt UpgradeCode, können Sie diese Funktion nicht verwenden.

Mike Dimmick
quelle
21
Zweifellos weiß Mike genau, wovon er spricht, bei allem Respekt, aber ich seufze verzweifelt, wenn ich darüber nachdenke, meine Gedanken mit einem festen Verständnis dessen, was der Windows Installer tut, zu überladen. Bevor ich es weiß, werde ich Enterprise-Kunden in den gottesfürchtigen Tech-Center-Städten jenseits der Ringstraße Java- und .NET-Beratungsaufgaben erledigen, meine TPS-Berichte ausfüllen und mich fragen, warum das Leben so leer erscheint. Ich denke, mein nächstes Projekt könnte mit NSIS installiert werden, was mich trotz all seiner Fehler, wie einer absurden Assembler-ähnlichen Sprache, nicht verstehen ließ, was Windows Installer tut.
Jonathan Hartley
2
@Tartley - gehen Sie mit InnoSetup, das erspart Ihnen die Assembler-ähnliche Sprache :) Stellen Sie sicher, dass Sie auch IStool greifen, es hilft sehr. Auch - stimmte zu, dass für einfache Installationen all dies viel zu kompliziert ist, aber ich denke, dass sie diese Komplexität wirklich brauchen, um so etwas wie SQL Server 2008 zu installieren ...
Roman Starkov
11

Ich habe diese Website verwendet, um die Grundlagen des WiX-Upgrades zu verstehen:

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

Danach habe ich ein Beispielinstallationsprogramm erstellt (eine Testdatei installiert) und dann das Upgrade-Installationsprogramm erstellt (2 Beispieltestdateien installiert). Dies gibt Ihnen ein grundlegendes Verständnis der Funktionsweise des Mechanismus.

Und wie Mike in dem Buch von Apress, "The Definitive Guide to Windows Installer", sagte, hilft es Ihnen zu verstehen, aber es ist nicht mit WiX geschrieben.

Eine andere Seite, die ziemlich hilfreich war, war diese:

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

CheGueVerra
quelle
Das Beispiel auf der Seite funktioniert nicht wie erwartet. Wix.tramontana.co.hu/tutorial/upgrades-and-modularization/… . Ich habe damit gespielt. Es ist sogar möglich, ein Downgrade
durchzuführen,
10

Ich habe die WiX- Dokumentation gelesen , Beispiele heruntergeladen, aber ich hatte immer noch viele Probleme mit Upgrades. Kleinere Upgrades führen keine Deinstallation der vorherigen Produkte durch, obwohl die Möglichkeit besteht, diese zu deinstallieren. Ich verbrachte mehr als einen Tag mit Nachforschungen und stellte fest, dass WiX 3.5 ein neues Tag für Upgrades einführte. Hier ist die Verwendung:

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

Der Hauptgrund für die Probleme war jedoch, dass in der Dokumentation angegeben ist, dass die Parameter " REINSTALL = ALL REINSTALLMODE = vomus " für kleinere und kleine Upgrades verwendet werden sollen. Es heißt jedoch nicht, dass diese Parameter für größere Upgrades VERBOTEN sind - sie funktionieren einfach nicht mehr. Sie sollten sie daher nicht für größere Upgrades verwenden.

Sasha
quelle
7

Ich würde vorschlagen, sich Alex Shevchuks Tutorial anzuschauen. Er erklärt das "Haupt-Upgrade" über WiX anhand eines guten praktischen Beispiels unter Von MSI zu WiX, Teil 8 - Haupt-Upgrade .

Faraz
quelle
Danke für den Link zu diesem Artikel ... es ist fantastisch!
Robert P
7

Eine wichtige Sache, die ich in den Tutorials für eine Weile verpasst habe (gestohlen von http://www.tramontana.co.hu/wix/lesson4.php ), führte zu den Fehlern "Eine andere Version dieses Produkts ist bereits installiert":

* Kleine Updates bedeuten kleine Änderungen an einer oder mehreren Dateien, bei denen die Änderung keine Änderung der Produktversion (major.minor.build) rechtfertigt. Sie müssen auch die Produkt-GUID nicht ändern. Beachten Sie, dass Sie die Paket-GUID immer ändern müssen, wenn Sie eine neue MSI-Datei erstellen, die sich in jeder Hinsicht von den vorherigen unterscheidet. Das Installationsprogramm verfolgt Ihre installierten Programme und findet sie, wenn der Benutzer die Installation mithilfe dieser GUIDs ändern oder entfernen möchte. Die Verwendung derselben GUID für verschiedene Pakete verwirrt den Installer.

Kleinere Upgrades kennzeichnen Änderungen, bei denen sich die Produktversion bereits ändert. Ändern Sie das Versionsattribut des Produkt-Tags. Das Produkt bleibt unverändert, sodass Sie die Produkt-GUID nicht ändern müssen, sondern natürlich eine neue Paket-GUID erhalten.

Wichtige Upgrades bedeuten wesentliche Änderungen wie den Wechsel von einer Vollversion zur anderen. Ändern Sie alles: Versionsattribut, Produkt- und Paket-GUIDs.

Daniel Morritt
quelle
3
Paket: ID-Typ: AutogenGuid Beschreibung: Die Paketcode-GUID für ein Produkt oder ein Zusammenführungsmodul. Beim Kompilieren eines Produkts sollte dieses Attribut nicht festgelegt werden, damit der Paketcode für jeden Build generiert werden kann. Beim Kompilieren eines Zusammenführungsmoduls muss dieses Attribut auf die Modularisierungsrichtlinie gesetzt werden. ---- Wir müssen also nicht auf die Paket-ID achten, oder?
Cooper.Wu
Ihr Link ist tot
bam500
5

Ich verwende die neueste Version von WiX (3.0) und konnte das oben genannte nicht zum Laufen bringen. Aber das hat funktioniert:

<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>

Beachten Sie, dass PUT-GUID-HERE mit der GUID übereinstimmen sollte, die Sie in der UpgradeCode-Eigenschaft des Produkts definiert haben.

Merill Fernando
quelle
2

Unten hat für mich gearbeitet.

<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>

Stellen Sie sicher, dass der UpgradeCode im Produkt mit der ID im Upgrade übereinstimmt.

NishantJ
quelle
1

Dies ist, was für mich funktioniert hat, auch mit der Hauptnote DOWN :

<Wix ...>
  <Product ...>
    <Property Id="REINSTALLMODE" Value="amus" />
    <MajorUpgrade AllowDowngrades="yes" />
Gian Marco Gherardi
quelle