Running a Custom Action on conditions issue - wix

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)

Related

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").

RegistrySearch vs util:RegistrySearch in Burn

I am using Burn to build a WiX bootstrapper. I realized that RegistrySearch as shown below does not actually search the registry. I used Process Monitor to monitor registry access.
<Property Id="NETFX35VERSION" Secure="yes">
<RegistrySearch Id="RegSearchNetFx35" Root="HKLM"
Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v3.5"
Name="Version" Type="raw" />
</Property>
However, when I used the util function it was working fine and the registry got queried fine:
<util:RegistrySearch Root="HKLM"
Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v3.5"
Value="Version"
Variable="NETFX35VERSION" />
Is this expected behavior with the WiX Burn tool?
Property and RegistrySearch are concepts for .msi packages. Bundles (bootstrappers) aren't processed by the MSI engine so they have other concepts, like Variable and util:RegistrySearch. They're similar and generally bundles have more functionality in searches than the MSI equivalent.

Wix Toolset - Setting a Property to User Profile Folder path and Program Files

I am using Properties to set the values of Registry entries. This is so that on install the first time I have a default value and then on upgrade the current registry value is used.
I need to have a property that sets the path to the user's local folder and to the programs folder. I know the below code is wrong but how do I do it. I think at least I want to do a Type 51 custom action but don't understand the documentation.
I believe there are three relevant parts
<InstallExecuteSequence>
<Custom Action="SetUserFolder" Before="InstallInitialize"/>
<Custom Action="SetInstallFolder" Before="InstallInitialize"/>
</InstallExecuteSequence>
Custom Action
<CustomAction Id="SetUserFolder" Property="UserFolder" Value="[%USERPROFILE]" />
<CustomAction Id="SetInstallFolder" Property="P_InstallFolder" Value="[%PROGRAMFILES]" />
The property.
<Property Id="P_MyAPPPATH" Value="[P_InstallFolder]MyApp\">
<RegistrySearch Id="S_MyAppPath" Type="raw" Root="HKCU" Key="Software\MyApp\Settings" Name="MyAppPath"/>
</Property>
<Property Id="P_MyAPPDB" Value="[UserFolder]\MyApp\MyAppData\">
<RegistrySearch Id="S_MyAPPDB" Type="raw" Root="HKCU" Key="Software\MyApp\Settings" Name="MyAppdb"/>
</Property>
As an alternative to using the properties you're defining, you might be able to use some built-in properties to better effect.
Instead of %USERPROFILE, consider LocalAppDataFolder. This will avoid your data from being copied between machines as a user roams between machines on a network domain. I'm guessing you don't need that but, if you do, use AppDataFolder and beware of the latencies involved.
Instead of %PROGRAMFILES, consider ProgramFilesFolder. This seems to be what you intend.

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 ]]>

Registry not being read when using registrysearch in Wix

I have been searching the internet for an answer on this registry search issue.
I have a bigger wix file but i could not get multiple features working and its the conditioning of the features so I have created a basic test wix document to understand the features of wix but can not get the result i required.
The code is as follows:
<Property Id="BASICTEST" Secure="yes" >
<RegistrySearch Id="_Regsearch_Basic" Root="HKLM"
Key="SOFTWARE\TGSL\BasicInstaller" Name="BASIC1" Type="raw" >
</RegistrySearch>
</Property>
<Property Id="BASICTEST1" Secure="yes" >
<RegistrySearch Id="_Regsearch_Test" Root="HKLM"
Key="SOFTWARE\TGSL\BasicInstaller" Name="TEST1" Type="raw" >
</RegistrySearch>
</Property>
<Feature Id="BasicFeature" Title="BasicFeat" Level="0">
<Condition Level="1">NOT (BASICTEST="0")</Condition>
<ComponentRef Id="BasicTest"/>
</Feature>
<Feature Id="TestFeature" Title="TestFeat" Level="0" >
<Condition Level="1">NOT (BASICTEST1="0") </Condition>
<ComponentRef Id="BasicTest1"/>
</Feature>
I have set up four registry entries, all values are 1 (BASIC1=1 and TEST1=1) to test which registry it is using (either 2 in SOFTWARE\TGSL\BasicInstaller for 64bit or 2 in SOFTWARE\TGSL\BasicInstaller for 32bit)
I know it defaults to 32bit unless otherwise stated but still nothing. I was using process monitor to test to see if my .msi file was reading the registry...which it isnt.
I created a log file when installing the .msi and i get a error code when reading the registry:
AppSearch: Property: BARRIETEST, Signature: _Regsearch_BarrieTest1
Note: 1: 2262 2: Signature 3: -2147287038
Note: 1: 1402 2: HKEY_LOCAL_MACHINE32\SOFTWARE\TGSL\BasicInstaller 3: 2
The error code is not finding the file but it looks like it is looking in a directory that doesnt exist and when i change it to win64="yes" it takes away the 32 after the HKEY_LOCAL_MACHINE.
I have tried building this test script in wix 2.0 and it searches the registry fine and it changes the property to the value of the registry key "1" so i am in a quandary as to what im doing wrong??
Is there a difference between the registry search parameters between wix 2.0 and wix 3.5?
Can anyone suggest a possible fix or how i can get these features working?
Please help...thank in advance
For closure, as indicated in the question comments, this was a permissions issue where the user running the setup installer did not have enough privileges to access HKEY_LOCAL_MACHINE.