Check 3rd party software version installed - wix

I'm filling property with installed office version
<Property Id="VISIOVERSION">
<RegistrySearch Id="VisioVersion14x64"
Root="HKLM"
Key="SOFTWARE\Microsoft\Office\14.0\Visio"
Name="InstalledVersion"
Type="raw" Win64="yes" />
</Property>
How can I compare this version with a minimum version required? Versions look like 14.0.5432.3

If office version 14.0.5432.3 is minimum version required, try this condition.
<Condition Message="Minimum office version 14.0.5432.3 is required to continue the installation.">
(VISIOVERSION >= "14.0.5432.3")
</Condition>

A LaunchCondition should help out here. Checking that the prerequisite version is high enough is a simple >= operation. However, it is important to always include Installed in your LaunchConditions to ensure that your software can be uninstalled if the prerequisite was removed first. A full example:
<Condition Message="Viso v14.0.5432.3 or newer is required before installing [ProductName].">
Installed OR (VISIOVERSION >= "14.0.5432.3")
</Condition>

Related

How can I detect whether .NET Framework 3.5 or higher is installed in WiX?

I currently using the following markup in my WiX installer project to check if .NET Framework 3.5 or greater is installed.
there is no Release Reg_DWORD for .Net Framework 3.5 But you can detect it using the following RegistrySearch:
<Property Id="NET35INSTALLED" Secure="yes" Admin="yes"/>
<util:RegistrySearch
Id="Net35Installed"
Variable="NET35INSTALLED"
Root="HKLM"
Key="Software\Microsoft\NET Framework Setup\NDP\v3.5"
Value="Install"
Win64="no"
Format="compatible"
/>
To use it in a condition use NET35INSTALLED = 1.
See more information in the official documentation.
Visit :
https://www.mking.net/blog/detecting-dotnet-framework-versions-with-wix
there you see the check for 4.7.2 installed :
<PropertyRef Id='WIXNETFX4RELEASEINSTALLED'/>
<Condition Message='This setup requires the .NET Framework 4.7.2 (or greater) to be installed.'>
<![CDATA[Installed OR (WIXNETFX4RELEASEINSTALLED >= "#461808")]]>
</Condition>
You only need to replace the release key with the 3.5 version..

Wix condition evaluation

I have a wix project and inside it I am checking whether c++ redist 2015 is installed or not as followings:
<Property Id="CPP2015REDISTX64">
<RegistrySearch Id="CPP2015RedistX64_RegKey" Type="raw" Root="HKLM"
Key="SOFTWARE\Microsoft\VisualStudio\14.0\VC\VCRedist\x64"
Name="Installed"
Win64="yes"/>
</Property>
<Condition Message='[Error Message]'>
CPP2015REDISTX64
</Condition>
When I try to install the package it shows me an error,but when I check my computer registries I can see it installed
I am wondering what's wrong with my code (I know that if the value of the Installed key is found it will proceed with the installation process and the condition will evaluate to true)
According to MSDN page Redistributing Visual C++ Files, the correct registry key to check is:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64
That matches what I see on my machine using regedit.exe.
So replace "VCRedist" by "Runtime". Also make sure that you specify -arch x64 on the candle.exe command-line (alternatively set Package/#Platform="x64", but the docs state that "use of this attribute is discouraged").

Check first install and registry value not exists in Wix

<![CDATA[(NOT Installed) AND (ACCESSRUNTIMECHECK <> "Access.Application.12")]]>
I was using the above expression to check if I am installing the first time and also if the ACCESSRUNTIMECHECK (a property from registry) value not matching the above value. However its not working correctly. whats wrong?
I am sure that the value of ACCESSRUNTIMECHECK is equal to "Access.Application.12".
<Property Id="ACCESSRUNTIMECHECK">
<RegistrySearch Id="AccessRuntimeSearch"
Root="HKLM"
Key="SOFTWARE\Classes\Access.Application\CurVer"
Type="raw" />
</Property>
<Condition Message="Access not installed!">
<![CDATA[(NOT Installed) AND (ACCESSRUNTIMECHECK <> "Access.Application.12")]]>
</Condition>
The expression has to evaluate to true to allow installation. The "or Installed" is meant to prevent the lack of Access from interfering with a repair / uninstall.
<Condition Message="Access not installed!">
ACCESSRUNTIMECHECK ~= "Access.Application.12" Or Installed
</Condition>

How to assign ANY value to WiX variable?

Imagine you have a variable called programVersion. We use this variable to publish on registry the version of our application in HKLM.
We have some conditions to check if a specific version OF ANOTHER PROGRAM is installed on our machine checking this registry values:
<Property Id="ANOTHER_APP_INSTALLED">
<RegistrySearch Id="AnotherAppInstalled" Root="HKLM"
Key="$(var.keyPathProgram)$(var.AnotherProgramVersion)"
Name="Path"
Type="raw" />
</Property>
But now I created a new version of the OTHER program, and I want to check if the older version or this newer exist on my registry on my NEW application. So I need to check both versions like this:
<Property Id="ANOTHER_APP_INSTALLED">
<RegistrySearch Id="AnotherAppInstalled" Root="HKLM"
Key="$(var.keyPathProgram)$(var.AnotherProgramVersion)"
Name="Path"
Type="raw" />
</Property>
<Property Id="ANOTHER_APPV11_INSTALLED">
<RegistrySearch Id="AnotherAppV11Installed" Root="HKLM"
Key="$(var.keyPathProgram)$(var.AnotherProgramVersion11)"
Name="Path"
Type="raw" />
</Property>
Is there any way to put an asterisk after a variable, that accepts any value after it? Something like this:
<Property Id="ANOTHER_APP_INSTALLED">
<RegistrySearch Id="AnotherAppInstalled" Root="HKLM"
Key="$(var.keyPathProgram)$(var.AnotherProgramVersion)*"
Name="Path"
Type="raw" />
</Property>
Here's the way I check if any of them is installed:
<![CDATA[ ANOTHER_APP_INSTALLED or ANOTHER_APPV11_INSTALLED ]]>
RECAP:
So I have an installed program on my machine that checks if another application is installed in any version, not my own application. I need it to check if that other application is installed in any of its possible versions.
EDIT: I need to ckeck if v1, v1.1, v1.2, v1.3... is installed. But I need to allow all of them to be a possible installed version, not only one of them. I need to check for every version that exists of the product.
I know this is not the regular behaviour of WiX, but I need it to behave like that.
Update
Generally, applications put the installed version in a key which is common to all of it's versions for example InstalledVersion key. Once you have read the value from this key you can then use it to allow or disallow installation of your application using WIX conditions.
<Condition Message="This setup requires OTHER software version 1 or higher.">
<![CDATA[OtherSoftwareVersionProperty >= "1"]]>
</Condition>
The above condition will allow your software to be installed for ANY version of OTHER software which is greater than 1.
or use this to allow installation only when specific versions are found:
<Condition Message="This setup requires OTHER software version 1.1.1 or 1.1.2.">
<![CDATA[OtherSoftwareVersionProperty = "1.1.1" OR OtherSoftwareVersionProperty = "1.1.2"]]>
</Condition>
But if your OTHER software creates separate keys for all it's versions then you will have to use a separate registry search for each one of them and then use them in a single condition as explained above.
Following answer does not make much sense after the OP updated the question
If all you want to do is check for versions of your program and prevent or allow upgrades and downgrades then I think you should look at the MajorUpgrade element. There is also a good tutorial on How To: Implement a Major Upgrade In Your Installer.
If you just want to prevent upgrades and downgrades then you can use
<MajorUpgrade AllowDowngrades="no" DowngradeErrorMessage="A newer version of [ProductName] is already installed." Disallow="yes" DisallowUpgradeErrorMessage="Please remove previous version of [ProductName]." />
Make sure you add an UpgradeCode attribute to your Product element.
If any Registry search is fine then why not search till little upper level like
Something like
<RegistrySearch Id="AnotherAppV11Installed" Root="HKLM"
Key="$(var.keyPathProgram)"
Name="Path"
Type="raw" />
Or You can also use FileSearch element to Detect Certain File version of your Another program and in Blocker Use like
<![CDATA[ ANOTHER_APP_INSTALLED <10.0 ]]>

Running a Custom Action on conditions issue

Can anyone tell me why this is not working please?
I have two registry checks to check if Visual C++ Redistributables are installed:
<Property Id="REGDBKEYEXISTX64">
<RegistrySearch Id="REGDBKEYEXISTX64" Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\{837b34e3-7c30-493c-8f6a-2b0f04e2912c}" Name="Version" Type="raw" Win64="yes" />
</Property>
<!--Checking if Microsoft Visual C++ Redistributables are installed on a 32-bit system-->
<Property Id="REGDBKEYEXIST">
<RegistrySearch Id="REGDBKEYEXIST" Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\{837b34e3-7c30-493c-8f6a-2b0f04e2912c}" Name="Version" Type="raw" Win64="no" />
</Property>
I then run a custom action if they are not installed:
<Custom Action="InstallRedistributables" After="GetVariantName">Installed OR REGDBKEYEXISTX64 OR REGDBKEYEXIST</Custom>
However when the redistributables are installed it still runs the custom action which is what i do not want. I know it detects it as this is my log file:
Property: REGDBKEYEXIST, Signature: REGDBKEYEXIST
MSI (c) (4C:44) [12:19:04:989]: PROPERTY CHANGE: Adding REGDBKEYEXIST property. Its value is '#134276921'.
So what could be the problem? I have this done on another custom action and it works perfectly so i really don't know the solution.
It appears your condition is reversed. The REGDBKEYEXIST properties will be set if the registry key exists, and thus true when the search indicates the redistributable is present. So what you probably want is more like NOT REGDBKEYEXIST You also probably only want to run this on first time install (hence your reference to Installed). So I would suggest changing your condition to something more like the following:
NOT(Installed or REGDBKEYEXIST or REGDBKEYEXISTX64)