Aktualisieren Sie die individuelle Funktion in Wix-Feature-Tree, ohne andere Funktionen zu deinstallieren/aktualisieren)

StackOverflow https://stackoverflow.com/questions/1744105

Frage

Ich versuche, ein Setup -Projekt mithilfe zu erstellen Wix Dadurch kann ich mehrere Funktionen eines einzelnen Produkts installieren. Wie kann ich eines der installierten Funktionen (was unabhängig von den anderen installierten Funktionen) aktualisieren, ohne die anderen Funktionen im Feature-Baum neu installieren zu müssen?

Zum Beispiel möchte ich in der Lage sein, ein Projekt zu haben (zurück zu Hellowolrd) namens Hellowolrd, das (Überraschung) "Hallo Welt!" Druckt, druckt "Hello World!" auf dem Bildschirm. Nehmen wir an, ich habe drei dieser Hello World -Anwendungen, Hello World 1, Hello World 2 und Hello World 3., von denen jeder auf dem Bildschirm Hello World 1, 2 oder 3 respektvoll druckt. Ich möchte einen MSI erstellen, der standardmäßig alle drei "Funktionen" installiert, aber auch zu einem späteren Zeitpunkt die Aktualisierung jeder Funktion einzeln einzeln ermöglicht.

Hier ist mein Layout meiner Lösung:

Lösung Explorer http://img12.imageshack.us/img12/5671/olutionExplorerm.jpg

Meine Wix product.wxs -Datei sieht folgendermaßen aus:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="ca484210-c719-4b2e-b960-45212d407c11" Name="HelloWorldInstaller" Language="1033" Version="1.0.0.0" Manufacturer="HelloWorldInstaller" UpgradeCode="68eeb8cb-9ef3-443c-870c-9b406129f7ff">
        <Package InstallerVersion="200" Compressed="yes" />

        <Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />

        <!-- Create Directory Structure -->
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder">
                <Directory Id="INSTALLLOCATION" Name="Hello World" />
            </Directory>
            <Directory Id="DesktopFolder" Name="Desktop"/>
        </Directory>

        <DirectoryRef Id="INSTALLLOCATION">
            <Component Id="HelloWorld1" Guid="6D1D9D33-DA17-4db3-8132-C39F32200C3A">
                <RegistryKey Root="HKCU" Key="Software\HelloWorldInstaller\HelloWorld1\Install" Action="createAndRemoveOnUninstall">
                    <RegistryValue Name="DTSC" Value="1" Type="integer" KeyPath="yes" />
                </RegistryKey>

                <File Id="HelloWorld1.exe" Name="$(var.HelloWorld1.TargetFileName)" Source="$(var.HelloWorld1.TargetPath)" DiskId="1" Checksum="yes">
                    <Shortcut Id="HelloWorld1ApplicationDesktopShortcut" Name="Hello World 1" Description="Hello World Application 1" Directory="DesktopFolder" WorkingDirectory="INSTALLLOCATION" />
                </File>

            </Component>
            <Component Id="HelloWorld2" Guid="B2D51F85-358B-41a7-8C45-B4BB341158F8">
                <RegistryKey Root="HKCU" Key="Software\HelloWorldInstaller\HelloWorld2\Install" Action="createAndRemoveOnUninstall">
                    <RegistryValue Name="DTSC" Value="1" Type="integer" KeyPath="yes" />
                </RegistryKey>

                <File Id="HelloWorld2.exe" Name="$(var.HelloWorld2.TargetFileName)" Source="$(var.HelloWorld2.TargetPath)" DiskId="1" Checksum="yes">
                    <Shortcut Id="HelloWorld2ApplicationDesktopShortcut" Name="Hello World 2" Description="Hello World Application 2" Directory="DesktopFolder" WorkingDirectory="INSTALLLOCATION" />
                </File>
            </Component>
            <Component Id="HelloWorld3" Guid="A550223E-792F-4169-90A3-574D4240F3C4">
                <RegistryKey Root="HKCU" Key="Software\HelloWorldInstaller\HelloWorld3\Install" Action="createAndRemoveOnUninstall">
                    <RegistryValue Name="DTSC" Value="1" Type="integer" KeyPath="yes" />
                </RegistryKey>

                <File Id="HelloWorld3.exe" Name="$(var.HelloWorld3.TargetFileName)" Source="$(var.HelloWorld3.TargetPath)" DiskId="1" Checksum="yes">
                    <Shortcut Id="HelloWorld3ApplicationDesktopShortcut" Name="Hello World 3" Description="Hello World Application 3" Directory="DesktopFolder" WorkingDirectory="INSTALLLOCATION" />
                </File>
            </Component>
        </DirectoryRef>

        <Feature Id="HelloWorld1Feature" Title="Hello World 1" Level="1">
            <ComponentRef Id="HelloWorld1"/>
        </Feature>
        <Feature Id="HelloWorld2Feature" Title="Hello World 2" Level="1">
            <ComponentRef Id="HelloWorld2"/>
        </Feature>
        <Feature Id="HelloWorld3Feature" Title="Hello World 3" Level="1">
            <ComponentRef Id="HelloWorld3"/>
        </Feature>

    </Product>
</Wix>

Wenn dies nun erstellt wird, installiert es die Funktionen, wie Sie es erwarten würden. Wenn Sie jedoch eine Änderung zu HelloWorld1.vb und neu kompilieren, möchte ich, dass es nur diese Funktion neu installieren kann (Upgrade), nicht alle von ihnen.

Wenn ich eine Datei aktualisiere und die Lösung neu aufbaue, versuche ich, den MSI zu installieren, erhalte ich diesen Fehler:

MSI -Fehler http://img696.imageshack.us/img696/849/anotherversionisinstall.jpg

Ich habe meinen Code aktualisiert, um das Deinstallieren der Funktionen zu ermöglichen und die Verwendung von Upgrade-Codes zu ermöglichen. Das hat jedoch alle Funktionen nicht installiert und alle von ihnen neu installiert.


-Anwendung realer Welt-

Die Real World -Anwendung dazu ist ein großes Softwarepaket, das mehrere Support -Anwendungen benötigt, die regelmäßig als Dienste/geplante Aufgaben ausgeführt werden. Ich möchte die Installation dieser unterstützenden Apps in einen MSI bringen, sodass wir nicht so einen Albtraum haben können, jedes Exe einzeln einzeln zu rollen. Ich weiß, wenn wir ein Update zu einem der EXE haben, können wir diese Exe einfach manuell kompilieren und ausrollen, aber ich würde dies gerne auf eine völlig reproduzierbare Weise tun.

Jede Hilfe würde beunruhigend sein,

Vielen Dank!

BEARBEITEN:

Ich habe die Quelle zum Download von hinzugefügt von Google -Code. Danke noch einmal!

War es hilfreich?

Lösung

Ich habe das herausgefunden und dachte, ich würde die Antwort hier als zukünftige Referenz für andere veröffentlichen. Ich habe das Problem voll und ganz erklärt, ich werde in mehr Tiefe des realen Szenarios eingehen.

Wir haben eine mäßig große Software, bei der wir mehrere unterstützende Anwendungen haben, die auf verschiedenen Servern ausgeführt werden. Unser aktueller Fortschritt der Upgrades macht es mäßig schwierig, Code auf zuverlässige Weise zu aktualisieren. Derzeit verwenden wir Self Extracting EXEs, um unseren Code für die verschiedenen Server zu rollen. Das Problem tritt auf, wenn wir eine so große Anzahl von unterstützenden Anwendungen haben, dass es schwierig wird, sicherzustellen, dass die Anwendungen mit den richtigen Konfigurationseinstellungen usw. korrekt installiert wurden, um dieses Problem zu lösen Bei den unterstützenden Anwendungen erstellen wir ein einzelnes Installationsprogramm (MSI), mit dem das Infrastrukturteam eine bestimmte Reihe von unterstützenden Anwendungen für jede gegebene Maschine installieren kann. Wenn wir eine große Änderung haben (z. B. von 1.0 bis 2.0), werden wir eine vollständige Upgrade-Installation durchführen (dh alle Dienste/Prozesse müssen gestoppt, nicht installiert, installiert und gestartet werden). Wenn wir eine geringfügige Änderung haben, Wir möchten nur die betroffenen Dienste/Prozesse anhalten und neu installieren müssen, ohne andere Anwendungen zu berühren. Jetzt genug von mir streift, lass uns gehen die Lösung:

Ich habe das Wix -Produkt geändert. Hier ist die aktualisierte WXS -Datei:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
 <Product Id="13C373D3-5C27-487e-A020-C2C89E4607B1" Name="HelloWorldInstaller" Language="1033" Version="1.0.0.0"
      Manufacturer="HelloWorldInstaller" UpgradeCode="E7CB3C76-4D51-48a8-BFB4-6D11B2E2E65B">

  <Package InstallerVersion="200" Compressed="yes" />

  <Media Id="1" Cabinet="product.cab" EmbedCab="yes" />
  <FeatureRef Id="HelloWorld1Feature" />
  <FeatureRef Id="HelloWorld2Feature" />
  <FeatureRef Id="HelloWorld3Feature" />
 </Product>

 <Fragment>
  <Directory Id="TARGETDIR" Name="SourceDir">
   <Directory Id="ProgramFilesFolder">
    <Directory Id="INSTALLLOCATION" Name="Hello World" />
   </Directory>
   <Directory Id="DesktopFolder" Name="Desktop"/>
  </Directory>
 </Fragment>

 <Fragment>
  <DirectoryRef Id="INSTALLLOCATION">
   <Directory Id="HelloWorld1Directory" Name="Hello World 1">
    <Component Id="HelloWorld1Component" Guid="6D1D9D33-DA17-4db3-8132-C39F32200C3A">
     <File Id="HelloWorld1.exe" Name="HelloWorld1.exe" Source="HelloWorld1.exe" DiskId="1" Checksum="yes" />    
    </Component>
   </Directory>
   <Directory Id="HelloWorld2Directory" Name="Hello World 2">
    <Component Id="HelloWorld2Component" Guid="B2D51F85-358B-41a7-8C45-B4BB341158F8">
     <File Id="HelloWorld2.exe" Name="HelloWorld2.exe" Source="HelloWorld2.exe" DiskId="1" Checksum="yes" />
    </Component>
   </Directory>
   <Directory Id="HelloWorld3Directory" Name="Hello World 3">
    <Component Id="HelloWorld3Component" Guid="A550223E-792F-4169-90A3-574D4240F3C4">
     <File Id="HelloWorld3.exe" Name="HelloWorld3.exe" Source="HelloWorld3.exe" DiskId="1" Checksum="yes" />
    </Component>
   </Directory>
  </DirectoryRef>
 </Fragment>

 <Fragment>
  <Feature Id="HelloWorld1Feature" Title="Hello World 1" Level="1">
   <ComponentRef Id="HelloWorld1Component"/>
  </Feature>
 </Fragment>
 <Fragment>
  <Feature Id="HelloWorld2Feature" Title="Hello World 2" Level="1">
   <ComponentRef Id="HelloWorld2Component"/>
  </Feature>
 </Fragment>
 <Fragment>
  <Feature Id="HelloWorld3Feature" Title="Hello World 3" Level="1">
   <ComponentRef Id="HelloWorld3Component"/>
  </Feature>
 </Fragment>
</Wix>

Jetzt werden wir für unsere kleineren Upgrades nach der Veröffentlichung von Patches für unsere Komponenten versuchen.

Angenommen, wir haben eine Produkta mit drei Komponenten - 1,2 und 3. Diese drei Komponenten müssen entweder als Dienstleistungen oder als geplante Aufgaben ausgeführt werden. In der Art unseres Produkts können wir nicht alle unsere Dienste zum Aktualisieren oder Beheben einer unserer Komponenten abschalten. Wenn wir also nach der Installation von Version 1.0 einen Fehler in Komponenten 2 finden, aber wir möchten nicht, dass 1 oder 3 von der Fix betroffen ist, die auf diesen Fehler angewendet wird, werden wir einen Patch für Komponente 2 veröffentlichen. Somit wird nur Komponente 2 betroffen.

Für unser schnelles Beispiel oben verwenden wir HelloWorld1, HelloWorld2 und HelloWorld3 als unsere drei Komponenten in unserer Softwareanwendung. Der Gedanke besteht

Um dies zu demonstrieren, habe ich die drei Konsolenanwendungen über "Hello World 1!", "Hello World 2!" Und "Hello World 3!" Erstellt. Nachdem wir den ersten MSI veröffentlicht haben, sagen wir, wir finden einen "Fehler", bei dem wir HelloWorld1 "Hallo Welt 1! Aktualisiert" haben müssen. stattdessen. Hier ist, was wir tun werden, um dies zu simulieren:

  1. Erstellen Sie das product.wixobj, indem Sie diesen Befehl in der Eingabeaufforderung ausführen:
    candle.exe Product.wxs
    Bitte denken Sie daran, dass das Wix -Install -Verzeichnis in Ihrer Pfadvariable sein sollte, um die Candle.exe oder einen der WIX -Befehle anzurufen. (Kurzes Tutorial zur Aktualisierung der Pfadumgebungsvariable) Führen Sie auch die Befehle im selben Verzeichnis wie Ihre Produktdatei aus.
  2. Erstellen Sie die erste Version Ihres Produkts (sagen wir 1.0):
    light.exe Product.wixobj -out ProductA-1.0.msi
  3. Finden Sie nun einen Fehler (ändern Sie die Ausgabe von HelloWorld1, um "Hallo Welt 1! Aktualisiert") zu sagen.) Aktualisieren Sie die Assemblerversion und Dateiversion. Dies ist wichtig, da Wix so sagen kann, dass die Exes unterschiedlich sind.
  4. Führen Sie den gleichen Befehl wie Schritt eins aus (für ein gutes Maß):
    candle.exe Product.wxs
  5. Führen Sie fast den gleichen Befehl wie Schritt 2 aus:
    light.exe Product.wixobj -out ProductA-1.1.msi
    Beachten Sie, dass dies Version 1.1 anstelle von 1.0 ist (dies ist der MSI mit unserem aktualisierten Code). Wir möchten dies jedoch nicht einfach installieren, weiter lesen.
  6. Hier ist der lustige Teil, wir erhalten den Unterschied in den beiden MSIs mit dem folgenden Befehl:
    torch.exe -p -xi ProductA-1.0.wixpdb ProductA-1.1.wixpdb -out Diff.WixMst
  7. Jetzt erstellen wir die Patch -Datei daraus (patch.wxs wird unten erläutert):
    candle.exe Patch.wxs
  8. Mit diesem Befehl erstellen wir jetzt die WixMSP -Datei:
    light.exe Patch.wixobj -out Patch.WixMsp
  9. Und jetzt der lustige Teil. Erstellen Sie die MSP -Datei mit diesem Befehl:
    pyro.exe Patch.WixMsp -out Patch.msp -t RTM Diff.Wixmst

Wenn alles nach Plan verlief, sollten Sie zwei MSI- und eine MSP -Datei haben. Wenn Sie den ersten MSI (producta-1.0.msi) installieren und HelloWorld1.exe ausführen, sollten Sie die Nachricht "Hello World 1!" Sehen. Führen Sie nur zum Spaß (und zum Beispiel) die anderen Anwendungen aus und lassen Sie sie laufen (ich habe einen Stopp eingebaut, um sie offen zu halten). Schließen Sie HelloWorld1.exe, da wir jetzt das Update für dieses EXE anwenden werden, aber wir werden dabei nicht HelloWorld2.exe oder helloWorld3.exe beeinflussen. Wenn Sie jetzt die Datei MSP (Patch.msp) installieren und dann HelloWorld1.exe ausführen, sehen Sie die aktualisierte Nachricht "Hello World 1! Aktualisiert".

Jetzt für die magisch Patch.WXS -Datei:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
 <Patch
   AllowRemoval="yes"
   Manufacturer="Dynamo Corp"
   MoreInfoURL="http://www.dynamocorp.com/"
   DisplayName="Sample Patch"
   Description="Small Update Patch"
   Classification="Update"
        >

  <Media Id="5000" Cabinet="RTM.cab">
   <PatchBaseline Id="RTM"/>
  </Media>

  <PatchFamilyRef Id="SamplePatchFamily"/>
 </Patch>

 <Fragment>
  <PatchFamily Id='SamplePatchFamily' Version='1.0.0' Supersede='yes'>
   <ComponentRef Id="HelloWorld1Component"/>
  </PatchFamily>
 </Fragment>
</Wix>

Sieht nicht nach viel aus, oder? Nun, die interessantesten Teile sind folgende:

  1. <PatchBaseline Id="RTM"/> - Wenn Sie sich erinnern, wird bei unserer Erstellung des Patch -MSI verwendet. Das "RTM" wird im letzten Schritt oben erwähnt: -t RTM - Diese müssen übereinstimmen.
  2. <ComponentRef Id="HelloWorld1Component"/> - Dies zeigt den Patch auf die richtige Komponente, um in unserem Fall HelloWorld1Component zu aktualisieren.

Wenn Sie suchen, scheint der obige Code bekannt zu sein, weil er von stammt Peter Marcus Blog: Wix: Erstellen eines Patchs mit dem neuen Patch -Gebäudesystem - Teil 3

Ich habe mich auch stark verlassen Alex Shevchuks Blog: Von MSI nach Wix, Teil 8 - Hauptaufstimmung

Wenn Sie sich fragen: "Wow, das sind viele Schritte, warum sollte jemand so viele Schritte machen?" Das ist richtig, integrieren, integrieren, integrieren! Wie machst Du das? Nun, das ist ein bisschen mehr Forschung und vielleicht ein Blog -Beitrag? - Wahrscheinlich. Um Sie auf den richtigen Fuß zu bringen, hier finden Sie einen tollen Artikel über Automatisieren Sie Releases mit MSBuild und Windows Installer XML.

Wow, ich hoffe du hast all das (alle beiden) gelesen und viel gelernt. Ich hoffe, das hilft jemand anderem als mir.

Vielen Dank!

Andere Tipps

Klingt so, als hätten Sie das Upgrade -Szenario herausgefunden, jetzt müssen Sie nur noch herausfinden Wo können Sie Entfernung existingprodukte in einem großen MSI -Upgrade platzieren so dass Funktionen nicht neu installiert werden, wenn sie sich nicht geändert haben :)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top