Mise à niveau en fonction individuelle fonctionnalités arbre WIX sans désinstaller / mettre à niveau un autre élément (s)

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

Question

Je suis en train de créer un projet d'installation en utilisant WIX qui me permettra d'installer plusieurs caractéristiques un seul produit. Comment puis-je mettre à jour l'une des fonctions installées (qui est indépendant des autres fonctions installées) sans avoir à réinstaller les autres fonctionnalités de la fonction arbre?

Par exemple, je veux être en mesure d'avoir un projet (retour à HelloWolrd) appelé HelloWolrd, qui (surprise) imprime « Bonjour tout le monde! » sur l'écran. Disons que j'ai trois de ces applications Bonjour tout le monde, Bonjour tout le monde 1, 2 Bonjour tout le monde, et Bonjour tout le monde 3. Chacun qui imprime sur l'écran Bonjour tout le monde 1, 2 ou 3, avec respect. Ce que je voudrais est de créer un MSI qui installe par défaut tous les trois de ces « caractéristiques », mais permet également la mise à niveau de chaque fonction individuellement à un moment ultérieur.

Voici ma mise en page de ma solution:

Explorateur de solutions http://img12.imageshack.us/img12/5671/solutionexplorerm .jpg

Mon fichier WIX Product.wxs ressemble à ceci:

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

Maintenant, quand cela est construit, il installe les fonctionnalités que vous attendez. Toutefois, lorsque vous effectuez une modification HelloWorld1.vb et recompiler, je voudrais qu'il soit en mesure de réinstaller (mise à niveau) que cette fonction, pas tous.

Quand je mets à jour un fichier, et reconstruire la solution, puis essayez d'installer le msi, je reçois cette erreur:

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

Je mis à jour mon code pour permettre la désinstallation des fonctionnalités et permettre l'utilisation des codes de mise à niveau, mais non installé toutes les fonctionnalités, et ré-installé tous.


- application du monde réel -

La vraie application du monde à c'est un grand logiciel qui a besoin d'applications multiples de soutien qui fonctionnent comme des services / tâches planifiées sur une base régulière. Je voudrais obtenir l'installons de ces applications de support dans un MSI qui nous permet de ne pas avoir un tel cauchemar de déployer chaque exe individuellement. Je sais que si nous avons une mise à jour l'une des années exe que nous pourrions simplement compiler manuellement que exe et le rouler, mais je voudrais faire cela d'une manière tout à fait reproductible.

Toute aide serait appriciated,

Merci!

EDIT:

J'ai ajouté la source pour le téléchargement à partir Google Code . Merci encore!

Était-ce utile?

La solution

Je suis ce a compris et pensé que je posterais la réponse ici pour référence future pour les autres. J'ai donc expliqué en détail le problème, je vais aller plus approfondie du scénario monde réel.

Nous avons un morceau modérément grand nombre de logiciels qui nous oblige à avoir de multiples applications prenant en charge qui fonctionnent sur un certain nombre de serveurs différents. Notre progression actuelle des mises à jour, il est modérément difficile de mettre à niveau le code de manière fiable. À l'heure actuelle, nous utilisons auto-extractible de exe pour déployer notre code aux différents serveurs. Le problème se pose lorsque nous avons un grand nombre d'applications de soutien qu'il devient difficile de faire en sorte que les applications se sont installées correctement avec les paramètres de configuration, etc. Pour résoudre ce problème, nous examinons la possibilité de au lieu de compresser chacun les applications de soutien, nous créons un seul installateur (MSI) qui permettra à l'équipe d'infrastructure pour installer un ensemble spécifique de supporter des applications à chaque machine donnée. Lorsque nous avons un changement majeur (par exemple de 1,0 à 2,0), nous procéderons à une mise à jour complète installer (ce qui signifie tous les services / processus devra être arrêté, non installé, installé et démarré.) Lorsque nous avons un changement mineur, nous voudrions avoir seulement pour arrêter et réinstaller les services concernés / processus, sans toucher d'autres applications. Maintenant, assez de moi décousu, permet d'obtenir à la solution:

Je modifié Wix Product.wxs pour supprimer les raccourcis que nous ne avons pas vraiment besoin d'eux dans notre scénario. Voici le fichier wxs mise à jour:

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

Maintenant avec cela, pour nos mises à jour mineures, nous allons examiner la libération des correctifs pour nos composants.

Par exemple, disons que nous avons un ProduitA, qui a trois composantes - 1,2 et 3. Ces trois composants doivent fonctionner soit en tant que services ou des tâches planifiées. La nature de notre produit, nous ne pouvons pas fermer tous nos services à mettre à jour ou corriger l'un de nos composants. Donc, si après que nous avons installé la version 1.0, on trouve un bug dans le composant 2, mais nous ne voulons pas 1 ou 3 d'être affectés par le correctif appliquée à ce bogue, nous publierons un patch pour le composant 2, ainsi que le composant 2 sera affectée.

Pour notre exemple rapide ci-dessus, nous utilisons HelloWorld1, HelloWorld2 et HelloWorld3 comme nos 3 composants dans notre application logicielle. La pensée est que nous devrions être en mesure d'installer tous les trois avec un MSI, puis mettre à jour chacun indépendamment sans affecter l'un des autres composants installés.

Donc, pour le démontrer, je l'ai créé les trois applications de la console ci-dessus qui affiche « Bonjour tout le monde 1! », « Bonjour tout le monde 2! », Et « Bonjour tout le monde 3! ». Puis, après nous libérons la MSI initiale, disons que l'on trouve un « bug » qui nous oblige à avoir HelloWorld1 dire « Bonjour tout le monde 1! Mise à jour. » au lieu. Voici ce que nous allons faire pour simuler ceci:

  1. Créer l'Product.wixobj en exécutant cette commande à l'invite de commande:
    candle.exe Product.wxs
    S'il vous plaît rappelez-vous que pour appeler le candle.exe ou l'une des commandes WIX, le répertoire d'installation Wix devrait être dans votre variable PATH. ( tutoriel sur la mise à jour variable d'environnement PATH ) En outre, s'il vous plaît exécuter les commandes dans le même répertoire que votre fichier Product.wxs.
  2. Créez la première version de votre produit (permet de dire 1.0):
    light.exe Product.wixobj -out ProductA-1.0.msi
  3. Maintenant, trouver un bug (changer la sortie de HelloWorld1 dire "Bonjour tout le monde 1! Mise à jour".) Puis mettre à jour la version de l'assemblage et la version du fichier . Ceci est important car voici comment WIX peut dire les exe sont différents.
  4. Exécuter la même commande que la première étape (pour faire bonne mesure):
    candle.exe Product.wxs
  5. Exécuter à peu près la même commande que la deuxième étape:
    light.exe Product.wixobj -out ProductA-1.1.msi
    Notez que ceci est la version 1.1 au lieu de 1.0 (ceest le msi avec notre code mis à jour). Cependant, nous ne voulons pas installer seulement cela, continuer à lire.
  6. Voici la partie amusante, nous obtenons la différence dans les deux avec la commande MSIs suivante:
    torch.exe -p -xi ProductA-1.0.wixpdb ProductA-1.1.wixpdb -out Diff.WixMst
  7. Maintenant, nous créons le fichier patch de ce (Patch.wxs sera expliqué ci-dessous):
    candle.exe Patch.wxs
  8. Nous allons maintenant créer le fichier WixMsp avec cette commande:
    light.exe Patch.wixobj -out Patch.WixMsp
  9. Et maintenant, la partie amusante. Créez le fichier MSP avec cette commande:
    pyro.exe Patch.WixMsp -out Patch.msp -t RTM Diff.Wixmst

Maintenant, si tout est allé selon le plan, vous devriez avoir deux années msi et un fichier msp. Si vous installez le premier msi (ProduitA-1.0.msi) et exécutez HelloWorld1.exe, vous devriez voir le message, « Bonjour tout le monde 1! ». Juste pour le plaisir (et par exemple), exécutez les deux autres applications et les laisser courir (je construit un arrêt pour les garder ouverts). Fermez HelloWorld1.exe que nous allons maintenant appliquer la mise à jour pour que exe, mais ce faisant, nous n'affectera HelloWorld2.exe ou HelloWorld3.exe. Si vous installez maintenant le fichier msp (Patch.msp), puis exécutez HelloWorld1.exe, vous verrez le message mis à jour, « Bonjour tout le monde 1! Mise à jour. »

Maintenant, pour la magique fichier 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>

Ne ressemble pas beaucoup, hein? Eh bien, les parties les plus intéressantes sont celles-ci:

  1. <PatchBaseline Id="RTM"/> - si vous rappelez est utilisé dans notre création du patch msi. Le « RTM » est mentionné dans la dernière étape ci-dessus. -t RTM - Ceux-ci doivent correspondre
  2. <ComponentRef Id="HelloWorld1Component"/> - Cela met le patch à la composante correcte de mettre à jour, dans notre cas HelloWorld1Component.

Si vous avez fait une recherche autour, le code ci-dessus peut sembler familier car il est venu de Blog de Peter Marcu : WiX: Construire un patch en utilisant le nouveau système de construction Patch - Partie 3

J'ai aussi beaucoup compté sur Blog Alex Shevchuk: de MSI à Wix, Partie 8 - Major Mise à jour

Si vous vous demandez, « Wow, c'est beaucoup d'étapes, pourquoi serait-on faire cela plusieurs étapes? », S'il vous plaît rappelez-vous qu'une fois le travail (ci-dessus) est fait, vous devez déplacer cela dans votre routine d'intégration . C'est vrai, d'intégrer, d'intégrer, intégrer ! Comment est-ce que tu fais ça? Eh bien, thats un peu plus de recherche, et peut-être un billet de blog? - Probablement. Pour vous aider à descendre sur le pied droit, voici un article impressionnant sur Automatiser les renonciations MSBuild et Windows Installer XML .

Wow, je l'espère vous lire tout cela (tous deux d'entre vous), et beaucoup appris. J'espère que cela aide quelqu'un d'autre que moi-même.

Merci!

Autres conseils

Sons comme vous avez compris le scénario de mise à niveau, maintenant, vous avez juste besoin de trouver

scroll top