RegistrySearch vs util:RegistrySearch in Burn - wix

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.

Related

Wix Bootstrapper bundle how to specify NOT condition for bal:Condition

What I want to do is:
<bal:Condition Message="Microsoft .NET v4.5.2 is required.">Not (WIX_IS_NETFRAMEWORK_452_OR_LATER_INSTALLED)</bal:Condition>
But it doesn't seem to recognize this syntax. How do I specify NOT in a bal:Condition (and where the heck would this ever be documented?)
Thanks.
So I couldn't figure out how to get that syntax right, nor could I find any decent documentation, anywhere, on this stuff, so I resorted to a registry search:
<util:RegistrySearch
Id="Is452There"
Root="HKLM" Key="SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"
Value="Release" Variable="Is452There" Win64="no" />
and then:
<bal:Condition Message="Microsoft .NET v4.5.2 is required.">Is452There>="379893"</bal:Condition>
This seemed to do the trick.

Is it possible to read from 64 and 32-bit registry entries in the same installation?

In my installation I need to check presence of 64-bit entry at first.
And read its value if it is present in 64-bit part of registry.
If entry is absent then I need to try to read this entry from 32-bit registry part(Wow6432Node).
I need to read it directly from wxs file or from custom action on VBScript.
Is it possible to do?
If you're running a 64bit MSI you can set two AppSearch/RegLocator entries using the style:
<Property Id="MY_32BIT_REG">
<RegistrySearch Id="my32bitreg"
Root="HKLM"
Key="SOFTWARE\My Company"
Name="foo"
Type="raw"
Win64="no" />
</Property>
<Property Id="MY_64BIT_REG">
<RegistrySearch Id="my64bitreg"
Root="HKLM"
Key="SOFTWARE\My Company"
Name="foo"
Type="raw"
Win64="yes" />
</Property>
These entries will check the appropriate "HKLM\SOFTWARE\My Company" and "HKLM\SOFTWARE\Wow6432Node\My Company" registry hives.

Wix registry editing not displayed in the msi log

I've been working on a WIX .net project that needs to update a Microsoft registry entry to work correctly. While testing the logic, I found it difficult to debug the WIX components that updates the registry via the MSiexec.exe command line /log options. To verify the correct behaviour, I had to check the registry value manually. How do I force the WIX project to log the registry search and update logic from the following fragment in the MSI log output?
<util:RegistrySearch Id="Office2013RegistySearch"
Root="HKLM"
Key="SOFTWARE\Microsoft\Office\15.0\Access Connectivity Engine\Engines\Excel"
Value="TypeGuessRows"
Variable="Office2013GuessRowsx86Exist"
Win64="no"
Result="exists" />
<Component Id="Office2013GuessRowsx86RegComponent" Guid="CFE579F9-292A-4777-A671-B5E8E330B1A0" Win64="no">
<Condition>Office2013GuessRowsx86Exists</Condition>
<RegistryKey Root="HKLM"
Key="SOFTWARE\Microsoft\Office\15.0\Access Connectivity Engine\Engines\Excel" ForceDeleteOnUninstall="no">
<RegistryValue Type="integer" Name="TypeGuessRows" Value="0"/>
</RegistryKey>
</Component>
Try use full log
msiexec /i "dotnetproject.msi" /L*v "log.log"
or add <Property Id="MsiLogging" Value="voicewarmup"/> (for full log too)

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)