Aggiornamento caratteristica individuale in funzione WIX-albero senza disinstallare / aggiornare altra caratteristica (s)

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

Domanda

Sto cercando di creare un progetto di installazione utilizzando WIX che mi permetterà di installare più caratteristiche di un singolo prodotto. Come posso aggiornare una delle funzioni installate (che è indipendente dalle altre funzioni installate) senza dover reinstallare le altre caratteristiche della funzione-albero?

Per esempio, io voglio essere in grado di avere un progetto (che risale al HelloWolrd) chiamato HelloWolrd, che (sorpresa) stampe "Ciao mondo!" sullo schermo. Diciamo che ho tre di queste applicazioni del mondo ciao, Ciao Mondo 1, Ciao Mondo 2, e Ciao Mondo 3. Ognuno di che stampa sullo schermo Ciao Mondo 1, 2, o 3, rispettosamente. Quello che vorrei è quello di creare un MSI che installa di default tutti e tre di queste "caratteristiche", ma permette anche l'aggiornamento di ogni caratteristica singolarmente in un secondo momento.

Ecco il mio layout della mia soluzione:

Esplora soluzioni http://img12.imageshack.us/img12/5671/solutionexplorerm .jpg

Il mio file WIX Product.wxs assomiglia a questo:

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

Ora, quando questo è stato costruito, installa le caratteristiche come ci si aspetterebbe. Tuttavia, quando si effettua una modifica al HelloWorld1.vb e ricompilare, vorrei che fosse in grado di reinstallare (aggiornamento) solo questa caratteristica, non tutti.

Quando aggiorno un file, e ricostruire la soluzione, quindi provare a installare il msi, ottengo questo errore:

Errore MSI http://img696.imageshack.us/img696/849/anotherversionisinstall .jpg

ho aggiornato il mio codice per consentire la disinstallazione delle caratteristiche e consentire l'utilizzo di codici di aggiornamento, ma che non installato tutte le caratteristiche, e reinstallato tutti loro.


- applicazione mondo reale -

L'applicazione mondo reale a questo è un pacchetto software di grandi dimensioni che ha bisogno di più applicazioni di supporto che vengono eseguite come servizi / attività pianificate su base regolare. Vorrei ottenere l'installazione di queste applicazioni di supporto in un MSI che ci permette di non abbiamo un tale incubo di stendere ogni exe singolarmente. So che se abbiamo un aggiornamento per una delle exe che potremmo semplicemente compilare manualmente che exe e stenderla, ma mi piacerebbe fare questo in modo completamente riproducibile.

Qualsiasi aiuto sarebbe appriciated,

Grazie!

EDIT:

Ho aggiunto la fonte per il download dal Google Code . Grazie ancora!

È stato utile?

Soluzione

Ho ottenuto questo capito e ho pensato postare la risposta qui per riferimento futuro per gli altri. Così ho ampiamente spiegato il problema, andrò a maggiore profondità del reale scenario del mondo.

Abbiamo un moderatamente grande pezzo di software che ci impone di avere molteplici applicazioni di supporto che girano su un certo numero di server diversi. La nostra attuale progressione di aggiornamenti rende moderatamente difficile aggiornare il codice in modo affidabile. Attualmente usiamo autoestraente exe al rollout nostro codice per i diversi server. Il problema sorge quando abbiamo un numero così elevato di applicazioni di supporto che diventa difficile fare in modo che le applicazioni ricevuti correttamente installati con le impostazioni corrette, ecc Per risolvere questo problema stiamo esaminando la capacità di comprimere anziché ciascuno di le applicazioni di supporto, si crea un singolo installatore (MSI) che permetterà la squadra infrastruttura per installare un insieme specifico di supportare applicazioni ad ogni determinata macchina. Quando abbiamo un grande cambiamento (ad esempio 1,0-2,0) faremo un aggiornamento completo di installazione (che significa tutti i servizi / processi dovrà essere fermato, non installato, installato e avviato.) Quando abbiamo un piccolo cambiamento, vorremmo avere solo per fermare e reinstallare i servizi / processi interessati, senza toccare le altre applicazioni. Ora, abbastanza di me vagante, consente di ottenere a la soluzione:

Ho modificato il WIX Product.wxs per rimuovere i collegamenti come non abbiamo realmente bisogno di loro nel nostro scenario. Ecco il file WXS aggiornamento:

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

Ora, insieme a questo, per i nostri aggiornamenti minori, ci occuperemo in rilasciando le patch per i nostri componenti.

Per esempio, diciamo che abbiamo un ProductA, che ha tre componenti - 1,2, e 3. Queste tre componenti devono funzionare sia come servizi o attività pianificate. La natura del nostro prodotto, non può chiudere tutti i nostri servizi di aggiornare o correggere uno dei nostri componenti. Quindi, se dopo abbiamo installato la versione 1.0, troviamo un bug nel componente 2, ma non vogliamo che 1 o 3 per l'incidenza della correzione viene applicata a questo bug, ci sarà il rilascio di una patch per la componente 2, quindi solo componente 2 sarà influenzato.

Per il nostro esempio veloce sopra, stiamo usando CiaoMondo1, HelloWorld2, e HelloWorld3 come i nostri 3 componenti nella nostra applicazione software. L'idea è che dovremmo essere in grado di installare tutti e tre a una MSI, ma quindi aggiornare ognuno indipendentemente senza influenzare qualsiasi degli altri componenti installati.

Quindi, per dimostrare questo, ho creato le tre applicazioni console di cui sopra che visualizza "Ciao Mondo 1!", "Ciao Mondo 2!", E "Ciao Mondo 3!". Poi, dopo rilasciamo l'iniziale MSI, consente di dire troviamo un "bug" che ci impone di avere CiaoMondo1 dire "Ciao a 1! Aggiornato". anziché. Ecco cosa faremo per simulare questo:

  1. Creare il Product.wixobj eseguendo questo comando al prompt dei comandi:
    candle.exe Product.wxs
    Si ricorda che al fine di chiamare il candle.exe o uno qualsiasi dei comandi WIX, Wix directory di installazione dovrebbe essere nella vostra variabile PATH. ( Breve tutorial su come aggiornare variabile d'ambiente PATH ) Inoltre, si prega di eseguire i comandi nella stessa directory come il file Product.wxs.
  2. Crea la prima versione del prodotto (diciamo 1,0):
    light.exe Product.wixobj -out ProductA-1.0.msi
  3. Ora trova un bug (cambiare l'output di CiaoMondo1 a dire "Ciao Mondo 1! Aggiornato".) Quindi su aggiornare la versione di montaggio e versione del file . Questo è importante in quanto questo è il modo WIX può dire l'exe sono diversi.
  4. Eseguire lo stesso comando di passo uno (per buona misura):
    candle.exe Product.wxs
  5. Esegui quasi lo stesso comando come fase due:
    light.exe Product.wixobj -out ProductA-1.1.msi
    Si noti che questa è la versione 1.1 invece di 1.0 (questoè il msi con il nostro codice aggiornato). Tuttavia, non vogliamo installare solo questo, continuare a leggere.
  6. Ecco la parte divertente, otteniamo la differenza tra i due file MSI con il seguente comando:
    torch.exe -p -xi ProductA-1.0.wixpdb ProductA-1.1.wixpdb -out Diff.WixMst
  7. Ora creiamo il file di patch da questo (Patch.wxs sarà spiegato di seguito):
    candle.exe Patch.wxs
  8. Passiamo ora creare il file WixMsp con questo comando:
    light.exe Patch.wixobj -out Patch.WixMsp
  9. E ora, la parte divertente. Creare il file MSP con questo comando:
    pyro.exe Patch.WixMsp -out Patch.msp -t RTM Diff.Wixmst

Ora, se tutto è andato secondo i piani, si dovrebbe avere due MSI e un file MSP. Se si installa la prima msi (ProductA-1.0.msi) ed eseguire HelloWorld1.exe, si dovrebbe vedere il messaggio, "Ciao Mondo 1!". Solo per divertimento (ed esempio), eseguire sia le altre applicazioni e lasciare loro esecuzione (ho costruito in una sosta per tenerli aperti). Chiudere HelloWorld1.exe come stiamo andando a applicare l'aggiornamento per questo exe, ma così facendo non ci influenzerà HelloWorld2.exe o HelloWorld3.exe. Se ora si installa il file MSP (Patch.msp), e quindi eseguire HelloWorld1.exe, si vedrà il messaggio aggiornato, "Ciao Mondo 1! Aggiornato".

Ora, per la magica file Patch.wxs:

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

Non sembra molto, vero? Ebbene, le parti più interessanti sono queste:

  1. <PatchBaseline Id="RTM"/> - Questo se vi ricordate è utilizzato nella nostra creazione del Msi patch. Il "RTM" è di cui al l'ultimo passo di cui sopra:. -t RTM - Questi devono corrispondere
  2. <ComponentRef Id="HelloWorld1Component"/> - Questo indica la patch per il componente corretto per aggiornare, nel nostro caso HelloWorld1Component.

Se hai fatto alcuna ricerca in giro, il codice di cui sopra può sembrare familiare perché proveniente da Il blog di Peter Marcu : WiX: Costruire una patch utilizzando il sistema di costruzione di nuove patch - Parte 3

Ho anche fatto affidamento su di Alex Shevchuk Blog : da MSI a WiX, Parte 8 - importante aggiornamento

Se vi state chiedendo, "Wow, che è un sacco di passi, perché qualcuno dovrebbe fare questo molti passi?", Ricorda che una volta che il duro lavoro (sopra) è fatto, è necessario spostare questo nella vostra routine di integrazione . Quello a destra, integrare, integrare, integrare ! Come fai a fare questo? Beh, questo è un po 'più di ricerca, e magari un post sul blog? - Probabilmente. Per farti fuori con il piede giusto, ecco un articolo impressionante sul Automatizzare Uscite Con MSBuild e Windows Installer XML .

Wow, spero di leggere tutto questo (tutte due di voi), e ho imparato molto. Spero che questo aiuta qualcuno diverso da me.

Grazie!

Altri suggerimenti

suona come voi capito lo scenario di aggiornamento, ora non vi resta che capire Dove posizionare RemoveExistingProducts in un importante aggiornamento MSI in modo che funzioni non vengono reinstallati se non sono cambiate:)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top