0
votes

WIX MSI perMachine installer writing installed property to HKCU instead of HKLM.

One of the symptoms is that the original logic I used to detect an attempt to install an older version of the product fails because I was depending on the Installed property to get defined on a system where an install had previously been executed. Just to be clear this logic has worked in the past but now I am doing regression testing and it failed.

I edited the msi with orca and modified the launch condition that tests for this. I changed the launch condition to "Installed" and the message to "Not installed" I then ran the installer on several systems where our application is installed. If Installed were true then the installer would run but in every case the installer displayed the message box meaning that it couldn't find the registry entry.

I looked in all these systems and the "installed" registry entry was located in HKCU/Software/company/product/installed=1 instead of in HKLM.

Also this is a 64 bit installer and when I run the installer it gets into the UI and I look at the task manager to make sure it is running the 64 bit version of msiexec which it is.

Here's the relevant WIX fragment which stopped working. See the 1st launch condition. I am adding the beginning of the Product ... section.

<Product Id="*"
 Name="$(var.ProductDisplayName)"
 Language="1033"
 Version="$(var.OurVersion)"
 Manufacturer="$(var.ProductAuthor)"
 UpgradeCode="$(var.ProductUpgradeCode)">
<Product Id="*"
 Name="$(var.ProductDisplayName)"
 Language="1033"
 Version="$(var.VayTekVersion)"
 Manufacturer="$(var.ProductAuthor)"
 UpgradeCode="$(var.ProductUpgradeCode)"
>

<Package
  Description="$(var.ProductDisplayName)"
  Comments="$(var.ProductDisplayComment)"
  Manufacturer="$(var.ProductAuthor)"
  InstallerVersion="301" Compressed="yes"
  Platform="$(var.Platform)"
  InstallScope="perMachine"
  InstallPrivileges="elevated"/>

<Upgrade Id="$(var.ProductUpgradeCode)">
<UpgradeVersion Minimum="$(var.OurVersion)"
    IncludeMinimum="no" 
    OnlyDetect="yes"   
    Property="NEWERPRODUCTFOUND" />
<UpgradeVersion
    Minimum="07.01.01001" IncludeMinimum="yes"
    Maximum="$(var.OurVersion)" IncludeMaximum="no"
    Property="PREVIOUSVERSIONSINSTALLED"/>
</Upgrade>

<InstallExecuteSequence>
  <RemoveExistingProducts After="InstallFinalize"/>
</InstallExecuteSequence>

<Condition 
    Message="A later version of the product is already installed. Setup  will now exit.">
    (NOT NEWERPRODUCTFOUND) OR (NOT Installed)
</Condition>

After I stared at the code a while I removed the "NOT Installed" logic and left

NOT NEWERPRODUCTFOUND

This isn't ideal but it works in most situations.

Anyone have an idea why the registry entry is getting placed in the wrong hive?

1

1 Answers

2
votes

An MSI package is per-machine when the ALLUSERS property is set to "1". In the WiX toolset, you can set this using the Package element InstallScope attribute is set to "perMachine".

Also, upgrades will not detect packages in the other install scope. In other words, per-machine cannot upgrade per-user and vice versa.

PS: "NOT Installed" in a LaunchCondition is a very strange thing to see. That would just try to block repair/uninstall.