0
votes

I have the following basic wix product:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Product Id="*" Name="TestWriteRegistry" Language="1033" Version="1.0.0.0" 
           Manufacturer="Granta Test" UpgradeCode="PUT-GUID-HERE">
    <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

    <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
    <MediaTemplate />

    <Feature Id="ProductFeature" Title="TestWriteRegistry" Level="1">
      <ComponentGroupRef Id="ProductComponents" />
    </Feature>
  </Product>

  <Fragment>
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLFOLDER" Name="TestWriteRegistry" />
      </Directory>
    </Directory>
  </Fragment>

  <Fragment>
    <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
            <Component Id="ProductComponent">
                <File Source ="TestFile.txt" />
            </Component>
        <Component Id="CESLicenseRegistry" Guid="*" >
            <RegistryKey Root="HKLM" Key="SOFTWARE\WOW6432Node\MySoftware\TestKeyRegistry">
                <RegistryValue Type="string" Name="ProductKey" Value="[PIDKEY]"/>
            </RegistryKey>
        </Component>
    </ComponentGroup>
  </Fragment>
</Wix>

I run this with: msiexec /i "TestWriteRegistry.msi" PIDKEY="123"

The first time I run this, it correctly adds the value in the registry.

I would like to get that if I run the msi again with a different key, this one is updated into the registry. At the moment running it with a different PIDKEY does not write the registry. I assume it is because the Guid for the component is the same so Windows Installer assumes no changes are needed.

Can anyone help me to achieve my intended behaviour?

2
Why do you need to change the license key? Typically licenses are better dealt with in your application for a variety of reasons, see this discussion.Stein Åsmul
@SteinÅsmul because I want the installer to update features when my license changes. Thanks for the link.Sergioet

2 Answers

4
votes

There is no such thing as running the "same" MSI again. That MSI file installed on the system is defined by it's ProductCode (and PackageCode) and when you try to install it again Windows sees that it's already installed and goes into maintenance mode, and the default action is probably a repair.

So you'd need to say something about what re-running the MSI is supposed to do. It's not clear if you want to run that MSI (say) 20 times and have 20 copies of the product on the system, if so you'd need to change the Product/Package codes and be aware that most of them would overwrite each other in strange ways. If you want an upgraded version of the product with a new product key then look at major upgrades a bit more - your majorupgrade element is rather sparse and you didn't post your Package or Product elements showing UpgradeCode etc.

0
votes

I think you must provide us with a better description of what you are trying to achieve. It doesn't sound like what you are planning is very "deployment friendly". What features do you want to change? Do you want to install more files, or do you just unlock more application functionality with the new key? Or perhaps both? You must have tried to input a new key during setup repair/modify? To do that I would use a custom action of some sort to write the key properly (grants you more control).

Note that writing license keys with component registry paths like you seem to be attempting, often causes people to overwrite or revert the license data with defaults when running major upgrades or even during patching. This is one of the few cases where I would recommend using a custom action for flexibility and control - you would still need to use caution though. Whatever you do, make sure to test your setup upgrade scenarios, and be careful with the conditioning of your custom action so it runs only when you want it to (for example not on uninstall or during patching).

I have never tried, but I think you can have the application itself trigger an install of a missing feature (set to not install by default) at any point. You should be able to do so from any "normal" language capable of making Win32 calls. I am on shaky ground since I have never tried it, but you could start with MsiConfigureFeature or MsiConfigureProductEx (it looks like the latter allows a command line to be passed, so you can do ADDLOCAL=FeatureName that you want installed). I couldn't find any sample code online for this. If you are using C# you could use DTF (part of the WiX toolkit). It is a .NET wrapper for the Win32 Windows Installer API. Very easy to use - no need for any COM interop or Win32 fiddling, just pure .NET classes to use.


If you ask for my honest opinion:

As indicated in the link I provided as a comment, I would remove all licensing dialogs from your setup, and add them to your application instead. There are many reasons as explained in the link: Installer with Online Registration for Windows Application.

The main drawback of keeping your licensing out of the setup is that you won't be able to automatically write a key to HKLM from the application when running as a standard user (unless you change the write permissions for your particular HKLM registry key as part of the installation so that regular users can write there - and then they all share the same key, which might not be what you want - and any user can also delete the key accidentially affecting all users).

I much prefer to keep licensing per-user based and write the license into HKCU. Then you can allow the user to change the license on the fly from within the application at any point. Any installer features you install will apply to all users though.