Search code examples
c#.netwixregistrywindows-installer

Product LaunchCondition in WiX if no RegistryValue or RegistryValue is below 1.3.44


(I need to get this to work for the Product / .msi directly, not by using Bundle / Burn.)

(I am using WiX 3.6.)

Fragment that puts a registry value into a variable

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
  <?include $(sys.CURRENTDIR)Deployment\Data\Statics.wxi ?>
  <Fragment>
    <util:RegistrySearch Root="HKCU" Key="$(var.Line.Reg.Path)" Value="Version" Variable="AppAlreadyInstalled" />
  </Fragment>
</Wix>

Main product with non-working condition

<Product Name="$(var.App.Title)" Manufacturer="!(loc.Company)" Language="!(loc.Lang)" Id="*" Version="$(var.VersionNumber)" UpgradeCode="$(var.App.UpgradeCode)">
    <Package Id="*" InstallerVersion="300" Compressed="yes" InstallScope="$(var.App.Elevation)" InstallPrivileges="limited" />
    <DirectoryRef Id="TARGETDIR" />
    <MajorUpgrade Schedule="afterInstallValidate" DowngradeErrorMessage="!(loc.Msi.NewerVersionInstalled)" />
    <Property Id='DiskPrompt' Value="$(var.App.Title) Installation Media" />
    <Media Id="1" Cabinet="Media.cab" EmbedCab="yes" DiskPrompt="#1" />
    <Icon Id="AppIcon" SourceFile="$(var.Icon.Path)" />

    <Condition Message="Newer version already installed.">
        <![CDATA[Installed OR AppAlreadyInstalled]]>
    </Condition>

    <Feature Id="ProductFeature" Level="1">
         ...
    </Feature>
</Product>
  • I believe AppAlreadyInstalled is never set at the moment because it is in a fragment in a different file.
  • Then I actually want the installation to proceed if the registry value is NOT found at all / does not exist.
  • But if it does it exist, I would like the installation to proceed only if the registry value is below a certain value e.g. proceed with installation only if AppAlreadyInstalled < 1.3.44; this sounds hard to achieve because the registry value is stored as a string with two full-stops / periods.
  • Note the registry check is not of the application to-be-installed, which is already taken care of by DowngradeErrorMessage.

Solution

  • WixUtilExtension:RegistrySearch is only for bundles. You need a plain RegistrySearch in the WiX namespace. You can use RegistrySearchRef to pull in a RegistrySearch from a separate fragment.

    However, you're right that a version comparison is problematic: MSI does ordinal string comparisons so 1.2 > 1.10. If the install directory is in the registry, you might be better off using a RegistrySearch combined with a DirectorySearch and a FileSearch. FileSearch can search by version using the MinVersion attribute so if there's a file with a version you can use to detect the product, it'll be more reliable than string comparisons.