Actualización de características individuales en WIX característica-árbol sin desinstalar/actualizar otra característica(s)

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

Pregunta

Estoy tratando de crear un proyecto de instalación utilizando WIX que me va a permitir instalar varias características de un producto único.¿Cómo puedo actualizar una de las características instaladas (que es independiente de las otras características instaladas) sin tener que volver a instalar el resto de las características en el árbol?

Por ejemplo, quiero ser capaz de tener un proyecto (volviendo a HelloWolrd) llamado HelloWolrd, que (sorpresa) imprime "Hola mundo!" en la pantalla.Vamos a decir que tengo tres de estas aplicaciones hello world, Hola Mundo 1, Hola Mundo 2, y Hola Mundo 3.Cada uno de los cuales se imprime en la pantalla Hola Mundo 1, 2, o 3, respectivamente.Lo que me gustaría es crear un MSI que por defecto instala todas las tres de estas "características", pero también permite la actualización de cada elemento de forma individual en un momento posterior.

Aquí está mi diseño de mi solución:

El Explorador de soluciones http://img12.imageshack.us/img12/5671/solutionexplorerm.jpg

Mi WIX Producto.wxs archivo se parece a esto:

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

Ahora, cuando esta se construye, instala las características que usted esperaría.Sin embargo, cuando se realiza una modificación a HelloWorld1.vb y volver a compilar, me gustaría ser capaz de volver a instalar (actualización) sólo esa característica, no todos de ellos.

Cuando me actualización de un archivo, y la reconstrucción de la solución, a continuación, intente instalar el msi, me sale este error:

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

He actualizado mi código para permitir la desinstalación de las características y permitir el uso de la actualización de los códigos, pero que onu-instalado todas las características, y volver a instalar todo de ellos.


-- La aplicación del mundo Real --

El mundo real de la aplicación a este es un gran paquete de software que requiere múltiples de apoyo a las aplicaciones que se ejecutan como servicios/tareas programadas sobre una base regular.Me gustaría conseguir la instalación de estas aplicaciones de apoyo en uno MSI lo que nos permite no tener una pesadilla de despliegue de cada exe de forma individual.Sé que si tenemos una actualización para uno de los exe que podríamos compilar manualmente que exe and roll, pero me gustaría hacer esta completamente en una manera reproducible.

Cualquier ayuda sería appriciated,

Gracias!

EDITAR:

He añadido la fuente para descargar desde Google Code.Gracias de nuevo!

¿Fue útil?

Solución

Tengo este averiguado y pensaba que iba a publicar la respuesta aquí para referencia en el futuro para otros.Así que les he explicado el problema, voy a ir a más profundidad del escenario real.

Tenemos una moderadamente gran pieza de software que nos obliga a tener múltiples aplicaciones que se ejecutan en un número de diferentes servidores.Nuestra progresión actual de actualizaciones hace moderadamente difícil para actualizar el código de manera confiable.En la actualidad utilizamos exe autoextraíble para el despliegue de nuestro código de los diferentes servidores.El problema surge cuando tenemos un gran número de aplicaciones de apoyo que se hace duro para asegurarse de que las aplicaciones que tengo instaladas correctamente con los ajustes de configuración correctos, etc.Para resolver este problema, estamos mirando la posibilidad de, en lugar de la compresión de cada una de las aplicaciones de apoyo, vamos a crear una sola installer (MSI) que permitirá que el equipo de infraestructura para instalar un conjunto específico de aplicaciones de apoyo a cada máquina.Cuando tenemos un cambio importante (por ejemplo, de 1.0 a la 2.0), vamos a hacer una actualización completa de instalar (es decir, todos los servicios/procesos necesita ser detenido, onu-instalado, instala y se inicia.) Cuando tenemos un cambio menor, nos gustaría sólo tiene que parar y volver a instalar los servicios afectados/procesos, sin tocar otras aplicaciones.Ahora, basta de mí divagando, le permite llegar a la solución:

He modificado el WIX Producto.wxs para eliminar los accesos directos como realmente no necesitamos en nuestro escenario.Aquí es la actualización de los wxs archivo:

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

Ahora junto con esto, para nuestro mejoras de menor importancia, vamos a estar buscando en la liberación de parches para nuestros componentes.

Por ejemplo, digamos que tenemos un ProductA, que consta de tres componentes: 1,2 y 3.Estos tres componentes deben ejecutar como servicios, o las tareas programadas.La naturaleza de nuestro producto, no podemos cerrar todos nuestros servicios para actualizar o corregir uno de nuestros componentes.Por lo tanto, si después de haber instalado la versión 1.0, nos encontramos con un error en el componente 2, pero no queremos que 1 o 3 para ser afectado por la corrección se aplica a este error, vamos a lanzar un parche para el componente 2, por lo que solo componente 2 se verán afectadas.

Para nuestro ejemplo anterior, estamos utilizando HelloWorld1, HelloWorld2, y HelloWorld3 como nuestros 3 componentes en nuestra aplicación de software.La idea es que debemos ser capaces de instalar los tres con una MSI, pero luego de la actualización de cada uno de forma independiente sin que afecte a cualquiera de los demás componentes instalados.

Así que, para demostrar esto, he creado las tres aplicaciones de consola por encima de que la pantalla "Hola Mundo 1!", "Hola Mundo 2!", y "Hello World 3!".A continuación, después de la liberación inicial de MSI, supongamos que nos encontramos con un "bug" que nos obliga a tener HelloWorld1 decir "Hola Mundo 1!Actualizado". en su lugar.Aquí es lo que vamos a hacer para simular este:

  1. Crear el Producto.wixobj mediante la ejecución de este comando en el símbolo del sistema:
    candle.exe Product.wxs
    Por favor, recuerde que con el fin de llamar la candle.exe o cualquiera de WIX comandos, Wix directorio de instalación debe estar en su variable de entorno PATH.(Breve tutorial sobre la actualización de la variable de entorno PATH) También, por favor, siga los comandos en el mismo directorio que el Producto.wxs archivo.
  2. Crear la primera versión de tu producto (digamos 1.0):
    light.exe Product.wixobj -out ProductA-1.0.msi
  3. Ahora encontrar un error (cambio de la salida de HelloWorld1 a decir "Hola Mundo 1!Actualizado".) entonces actualización de la versión del ensamblado y la versión del archivo.Esto es importante ya que esta es la forma en WIX puede decir que el exe son diferentes.
  4. Ejecutar el mismo comando como el paso uno (en buena medida):
    candle.exe Product.wxs
  5. Ejecutar casi el mismo comando como paso dos:
    light.exe Product.wixobj -out ProductA-1.1.msi
    Aviso que esta es la versión 1.1 en lugar de 1.0 (este es el msi con nuestro código actualizado).Sin embargo, no queremos sólo tiene que instalar esta, siga leyendo.
  6. Aquí está la parte divertida, se obtiene la diferencia en los dos paquetes Msi con el siguiente comando:
    torch.exe -p -xi ProductA-1.0.wixpdb ProductA-1.1.wixpdb -out Diff.WixMst
  7. Ahora vamos a crear el archivo de revisión a partir de este Parche.wxs será explicado a continuación):
    candle.exe Patch.wxs
  8. Ahora vamos a crear el WixMsp archivo con este comando:
    light.exe Patch.wixobj -out Patch.WixMsp
  9. Y ahora, la parte divertida.Crear el archivo MSP con este comando:
    pyro.exe Patch.WixMsp -out Patch.msp -t RTM Diff.Wixmst

Ahora, si todo iba de acuerdo al plan, usted debe tener dos msi y un archivo msp.Si instala el primer msi (ProductA-1.0.msi) y ejecutar HelloWorld1.exe usted debería ver el mensaje "Hola Mundo 1!".Sólo por diversión (y ejemplo), ejecutar otras aplicaciones y dejarlos en ejecución (I, construido en una parada para mantenerlos abiertos).Cerca de HelloWorld1.exe como ahora vamos a aplicar la actualización para que exe, pero, al hacerlo, no le afectan HelloWorld2.exe o HelloWorld3.exe.Si ahora instalar el msp (Parche.msp) de archivo y, a continuación, ejecute HelloWorld1.exe verá la actualización del mensaje, "Hola Mundo 1!Actualizado".

Ahora, para el mágico El parche.wxs archivo:

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

No parece mucho, no?Así, las partes más interesantes son estos:

  1. <PatchBaseline Id="RTM"/> - Esto si que recordar es utilizado en la creación de nuestra revisión msi.El "RTM" se refiere en el último paso anterior: -t RTM - Estos tienen que coincidir.
  2. <ComponentRef Id="HelloWorld1Component"/> - Este es el parche para el componente correcto para actualizar, en nuestro caso HelloWorld1Component.

Si usted ha estado haciendo cualquier buscando alrededor, el código anterior puede parecer familiar debido a que venían de Pedro Marcu del Blog: WiX:La construcción de una Revisión utilizando el Parche nuevo Sistema de Construcción - Parte 3

También se basó en gran medida en Alex Shevchuk del Blog: A partir de MSI a WiX, Parte 8 - Actualización Principal

Si usted se está preguntando, "Wow, eso es un montón de pasos, ¿por qué iba alguien a hacer esto muchos pasos?", por favor, recuerde que una vez que el trabajo duro (arriba) es de hecho, usted tiene que mover esto a la integración de rutina.Thats a la derecha, integrar, integrar, integrar!¿Cómo hacer esto?Bueno, eso es un poco más de investigación, y tal vez un post en el blog?- Probablemente.Para bajar con el pie derecho, aquí está un artículo impresionante en Automatizar Versiones Con MSBuild Y Windows Installer XML.

Wow, espero que lea todo esto (todos los dos de usted), y he aprendido mucho.Espero que esto ayude a alguien que no sea yo mismo.

Gracias!

Otros consejos

Suena como si descubrieras el escenario de actualización, ahora solo necesitas descubrir Dónde colocar los productos de eliminación de EXTERICISE en una importante actualización de MSI para que esas características no se reinstalen si no han cambiado :)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top