Hacer que el conjunto de instalación de WiX se actualice a la misma carpeta


¿Cómo puedo hacer una actualización importante a un conjunto de instalación (MSI) construido con Wix install en la misma carpeta que la instalación original?

La instalación se detecta correctamente como una actualización, pero la pantalla de selección de directorio sigue mostrándose y con el valor predeterminado (no necesariamente la carpeta de instalación actual).

¿Tengo que hacer un trabajo manual como guardar la carpeta de instalación en una clave de registro al instalar primero y luego leer esta clave al actualizar? Si es así, ¿hay algún ejemplo?

O hay alguna manera más fácil de lograr esto en MSI o WiX?

Como referencia, mi archivo WiX actual está a continuación:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi">
    <Product Id="a2298d1d-ba60-4c4d-92e3-a77413f54a53"
             Name="MyCompany Integration Framework 1.0.0"
             Language="1033"
             Version="1.0.0"
             Manufacturer="MyCompany"
             UpgradeCode="9071eacc-9b5a-48e3-bb90-8064d2b2c45d">

        <!-- Package information -->
        <Package Keywords="Installer"
                 Id="e85e6190-1cd4-49f5-8924-9da5fcb8aee8"
                 Description="Installs MyCompany Integration Framework 1.0.0"
                 Comments="Installs MyCompany Integration Framework 1.0.0"
                 InstallerVersion="100"
                 Compressed="yes" />

        <Upgrade Id='9071eacc-9b5a-48e3-bb90-8064d2b2c45d'>
            <UpgradeVersion Property="PATCHFOUND"
                            OnlyDetect="no"
                            Minimum="0.0.1"
                            IncludeMinimum="yes"
                            Maximum="1.0.0"
                            IncludeMaximum="yes"/>
        </Upgrade>

        <!-- Useless but necessary... -->
        <Media Id="1" Cabinet="MyCompany.cab" EmbedCab="yes" />

        <!-- Precondition: .NET 2 must be installed -->
        <Condition Message='This setup requires the .NET Framework 2 or higher.'>
            <![CDATA[MsiNetAssemblySupport >= "2.0.50727"]]>
        </Condition>

        <Directory Id="TARGETDIR"
                   Name="SourceDir">
            <Directory Id="MyCompany"
                       Name="MyCompany">
                <Directory Id="INSTALLDIR"
                           Name="Integrat"
                           LongName="MyCompany Integration Framework">
                    <Component Id="MyCompanyDllComponent"
                               Guid="4f362043-03a0-472d-a84f-896522ce7d2b"
                               DiskId="1">
                        <File Id="MyCompanyIntegrationDll"
                              Name="IbIntegr.dll"
                              src="..\Build\MyCompany.Integration.dll"
                              Vital="yes"
                              LongName="MyCompany.Integration.dll" />
                        <File Id="MyCompanyServiceModelDll"
                              Name="IbSerMod.dll"
                              src="..\Build\MyCompany.ServiceModel.dll"
                              Vital="yes"
                              LongName="MyCompany.ServiceModel.dll" />
                    </Component>

                    <!-- More components -->
                </Directory>
            </Directory>
        </Directory>

        <Feature Id="MyCompanyProductFeature"
                 Title='MyCompany Integration Framework'
                 Description='The complete package'
                 Display='expand'
                 Level="1"
                 InstallDefault='local'
                 ConfigurableDirectory="INSTALLDIR">
            <ComponentRef Id="MyCompanyDllComponent" />
        </Feature>

        <!-- Task scheduler application. It has to be used as a property -->
        <Property Id="finaltaskexe"
                  Value="MyCompany.Integration.Host.exe" />
        <Property Id="WIXUI_INSTALLDIR"
                  Value="INSTALLDIR" />

        <InstallExecuteSequence>
            <!-- command must be executed: MyCompany.Integration.Host.exe /INITIALCONFIG parameters.xml -->
            <Custom Action='PropertyAssign'
                    After='InstallFinalize'>NOT Installed AND NOT PATCHFOUND</Custom>
            <Custom Action='LaunchFile'
                    After='InstallFinalize'>NOT Installed AND NOT PATCHFOUND</Custom>

            <RemoveExistingProducts Before='CostInitialize' />
        </InstallExecuteSequence>

        <!-- execute comand -->
        <CustomAction Id='PropertyAssign'
                      Property='PathProperty'
            Value='[INSTALLDIR][finaltaskexe]' />
        <CustomAction Id='LaunchFile'
                      Property='PathProperty'
                      ExeCommand='/INITIALCONFIG "[INSTALLDIR]parameters.xml"'
                      Return='asyncNoWait' />

        <!-- User interface information -->
        <UIRef Id="WixUI_InstallDir" />
        <UIRef Id="WixUI_ErrorProgressText" />
    </Product>
</Wix>
Author: Peter Mortensen, 2008-09-11

3 answers

Hay un ejemplo en el tutorial de WiX: http://wix.tramontana.co.hu/tutorial/getting-started/where-to-install

<Property Id="INSTALLDIR">
  <RegistrySearch Id='AcmeFoobarRegistry' Type='raw'
    Root='HKLM' Key='Software\Acme\Foobar 1.0' Name='InstallDir' />
</Property>

Por supuesto, también tienes que establecer la clave del registro como parte de la instalación. Pegue esto dentro de un componente que es parte de la instalación original:

<RegistryKey
         Key="Software\Software\Acme\Foobar 1.0"
         Root="HKLM">
  <RegistryValue Id="FoobarRegInstallDir"
             Type="string"
             Name="InstallDir"
             Value="[INSTALLDIR]" />
</RegistryKey> 
 31
Author: Anthony Williams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-02 16:08:51

'Registry' está obsoleto. Ahora esa parte del código debería verse así:

<RegistryKey Id="FoobarRegRoot"
             Action="createAndRemoveOnUninstall"
             Key="Software\Software\Acme\Foobar 1.0"
             Root="HKLM">
  <RegistryValue Id="FoobarRegInstallDir"
                 Type="string"
                 Name="InstallDir"
                 Value="[INSTALLDIR]" />
</RegistryKey>
 5
Author: Serge SB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-17 12:11:10

Realmente no es necesario separar RegistryKey de RegistryValue en un caso simple como este. Además, el uso de HKMU en lugar de HKLM se encarga de ello, ya sea que esté haciendo una instalación de máquina o de usuario.

<RegistryValue
  Root="HKMU"
  Key="Software\[Manufacturer]\[ProductName]"
  Name="InstallDir"
  Type="string"
  Value="[INSTALLDIR]"
  KeyPath="yes" />
 4
Author: Jamie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-16 22:08:39