Search code examples
wixinstallationregistrywindows-installerwix3.8

Get WiX / MSI to install some registry always, preserve some pre-existing ones


I have a WiX installation that also needs to write some registry keys, and I was wondering if there's a way to tell WiX/MSI to

  • only create a key if it doesn't exist yet
  • always create/overwrite another key, even if it exists

I tried something like this:

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Product Id="*" Name="TestRegistry" Language="1033" Version="1.0.2"
             Manufacturer="Myself" UpgradeCode="PUT-GUID-HERE">
    <Package InstallerVersion="200" Compressed="yes" 
                     InstallScope="perUser" InstallPrivileges="limited" />
    <MajorUpgrade DowngradeErrorMessage="A newer version installed." />
                <MediaTemplate EmbedCab="yes" />
                <Feature Id="ProductFeature" Title="TestRegistry" Level="1">
      <ComponentRef Id="ProductComponents" />
    </Feature>
  </Product>

  <Fragment>
   <Directory Id="TARGETDIR" Name="SourceDir">
    <Directory Id="ProgramFilesFolder">
     <Directory Id="dirManufacturer" Name="Manufacturer">
      <Directory Id="INSTALLFOLDER" Name="TheProduct">
       <Component Id="ProductComponents" Guid="*" DiskId="1">
        <RegistryKey Root="HKCU" Key="Software\Manufacturer\TheProduct"
                     Action="createAndRemoveOnUninstall">
          <RegistryValue Type="string" Name="Install Directory" 
                         Value="[INSTALLFOLDER]" KeyPath="yes" />
          <RegistryValue Type="string" Name="Product Version" 
                         Value="[ProductVersion]" />
          <RegistryValue Type="string" Name="Default Language" Value="en" />
          <RegistryValue Type="string" Name="Web Site URL" 
                         Value="https://product.manufacturer.info/" />
        </RegistryKey>
       </Component>
      </Directory>
     </Directory>
    </Directory>
   </Directory>
  </Fragment>
</Wix>

and here, I'd like to always overwrite the Install Directory and Product Version keys with current values, but I would like to preserve other settings, like Default Language.

Is there any way to do this?

Right now, when I install 1.0.0 fresh on a new system, it creates the registry keys alright. When I uninstall it, they're gone - so far, so good.

But when I installed v1.0.1 and then - without uninstalling v1.0.1 - installed v1.0.2 on top of this, ALL the defined registry keys were updated and contained the default values defined in the WiX script - the changes I had made manually were wiped out.


Solution

  • You will need to break the registry values out to there own components and set the NeverOverwrite attribute on them

    <Component Id="DefaultLangaugeComponent" Guid="*" NeverOverwrite="yes">
      <RegistryKey Root="HKCU" Key="Software\Manufacturer\TheProduct"
                                         Action="createAndRemoveOnUninstall">
       <RegistryValue Type="string" Name="Default Language" Value="en" />
      </RegistryKey>
    </Component>