util:RegistrySearch "Registry key not found" when using variable inside Win64="$(var.Win64)" - wix

<util:RegistrySearch does not find registry keys when using a variable for yes/no for example: Win64="$(var.Win64)".
It works as expected if I use the string yes/no instead of the variable for example: Win64="yes".
The var.Win64 is set to yes/no via a build script which prompts us for which OS to build for. The logs show it is being set to yes properly before DetectBegin.
<!-- Variables.wxi: -->
<?define Win64 = "yes" ?>
<!-- Product.wxs -->
<?xml version="1.0" encoding="UTF-8"?>
<?include ..\Setup\Variables.wxi ?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Fragment>
<Variable Name="MyAppVersion" Type="version" Value="$(var.ProductVersion)" />
<Variable Name="RegMyAppVersion" Type="version" Value="0.0.0.0" />
<Variable Name="Win64Version" Type="string" Value="$(var.Win64)" />
<util:RegistrySearch Root="HKLM" Key="SOFTWARE\$(var.Manufacturer)\$(var.ProductName)"
Result="exists"
Value="Version"
Variable="RegMyAppExists"
Win64="$(var.Win64)"/>
<util:RegistrySearch Root="HKLM" Key="SOFTWARE\$(var.Manufacturer)\$(var.ProductName)"
Result="value"
Value="Version"
Variable="RegMyAppVersion"
Win64="$(var.Win64)"/>
<util:RegistrySearch Root="HKLM" Key="SOFTWARE\$(var.Manufacturer)\$(var.ProductName)"
Result="value"
Value="LicenseKey"
Variable="RegMyAppLicenseKey"
Win64="$(var.Win64)"/>
[0D30:2BAC][2014-03-21T08:32:03]i001: Burn v3.8.1021.0, Windows v6.1 (Build 7601: Service Pack 1)
[0D30:2BAC][2014-03-21T08:32:03]i000: Initializing version variable 'ROIPOSVersion' to value '1.9.26.0'
[0D30:2BAC][2014-03-21T08:32:03]i000: Initializing version variable 'RegROIPOSVersion' to value '0.0.0.0'
[0D30:2BAC][2014-03-21T08:32:03]i000: Initializing string variable 'Win64Version' to value 'yes'
[0D30:2BAC][2014-03-21T08:32:04]i000: Registry key not found. Key = 'SOFTWARE\MyMan\MyProd'
[0D30:2BAC][2014-03-21T08:32:04]i000: Registry key not found. Key = 'SOFTWARE\MyMan\MyProd'
[0D30:2BAC][2014-03-21T08:32:04]i000: Registry key not found. Key = 'SOFTWARE\MyMan\MyProd'
[0D30:2BAC][2014-03-21T08:32:04]i000: Setting numeric variable 'RegMyAppExists' to value 0
EDIT: I also get this warning in Visual Studio found in this post:
Warning 1 The 'Win64' attribute is invalid - The value '$(var.Win64)' is invalid according to its datatype 'http://schemas.microsoft.com/wix/2006/wi:YesNoType' - The '$' character, hexadecimal value 0x24, cannot be included in a name.
Also the "just remove Win64 altogether it will automatically figure it out" doesn't work on 64bit, still doesn't find the key.

I tried the suggestion again from here and just removed the Win64 attribute altogether.
It was able to find the registry key in 64bit now. I must have been mistaken before.

Related

WIx - "Registry key not found" when trying to see if a value of SQL SMO exists

It's been a while since I've done any WiX, but just found out that a bit of an existing bootstrapper exe I wrote ages ago, isn't actually doing what I thought it was - doh !! I've seen other people with similar issues, but I still can't figure out why it's not working.
I'm basically trying to determine if a particular version of SQL SMO is installed and am looking in the registry at this location:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL
Server\SharedManagementObjects\CurrentVersion
where there is a REG_SZ key called "Version" and it's set to something like 13.0.1601.5
Below is a mock-up of my code:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Bundle Name="RegReadTesterSetup" Version="1.0.0.0" Manufacturer="BigChris Inc" UpgradeCode="fcaa47db-3b55-474f-995d-2b0a0905fced">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
<util:RegistrySearch Id="IsSMOInstalled"
Root="HKLM"
Key="SOFTWARE\Microsoft\Microsoft SQL Server\SharedManagementObjects\CurrentVersion\Version"
Value="13.0.1601.5"
Win64="yes"
Result="exists"
Format="raw"
Variable="SMOInstalled"/>
<Chain>
<MsiPackage SourceFile="C:\Users\chris.moxon\AppData\Local\Temporary Projects\SimpleTextFileSetup\bin\Debug\SimpleTextFileSetup.msi"
Id="MYTEXT"
DisplayName="Big Chris Test File"
Visible="yes"
InstallCondition="SMOInstalled = 0"
SuppressSignatureVerification="yes"/>
</Chain>
</Bundle>
</Wix>
Note : The indented settings (Win64 & Format) are just some of my clutching at straws attempts to get it to work; but with or without these settings; run on a 64bit or 32bit machine, I always get (on machine's where this key does exist !):
Registry key not found. Key = 'SOFTWARE\Microsoft\Microsoft SQL Server\SharedManagementObjects\CurrentVersion\Version'
Setting numeric variable 'SMOInstalled' to value 0
in my log file; so the end result is that the SMOInstalled variable always gets to set to 0 and thus SMO ( or my text file ) is always installed.
I appreciate (or hope) that I must be doing something silly - but alas I have no idea what !!
Thanks in advance,
Big Chris.
This should work:
<util:RegistrySearch Id="IsSMOInstalled"
Root="HKLM"
Key="SOFTWARE\Microsoft\Microsoft SQL Server\SharedManagementObjects\CurrentVersion"
Value="Version"
Win64="yes"
Result="exists"
Variable="SMOInstalled"/>
You shouldn't need Format="raw" when doing a Result="exists" registry search.
The issue you are having is that you are mixing up what a key and value represent in the registry. The "Key" is the path you see at the bottom of regedit when you pick a registry location. The value is actually the name a registry value at the registry key location. In this case the Registry Value that you want is "Version" from the key "HKLM\SOFTWARE\Microsoft\Microsoft SQL Server\SharedManagementObjects\CurrentVersion" and you are seeing if that value exists or not (which will set SMOInstalled to 0 (not exists) or 1 (exists)).
If you want to get the actual version information (the "data" on the registry value) you need to use Result="value" and then SMOInstalled will be set to the data of the Registry Value or not defined if it does not exist.
To understand Win64="yes" you need to understand the difference between the 64bit registry and 32bit registry. On a 32 bit machine there is only one registry and I'm not sure how Win64='yes' registry searches behave. On a 64 bit machine there are two registry locations. One for 32-bit processes (x86) and one for 64-bit processes (x64). If explicitly specified you can view the other bitness' registry location from a certain bitness process but you need to be sure this is what you want to do. A 32 bit process on a 64bit machine that tries to look at the registry gets its registry keys redirected to SOFTWARE\Wow6432Node\abc\xyz... even though you only specified SOFTWARE\abc\xyz... .
If your program works with either the 32bit or 64bit SMO installed you'll likely have to check both registry locations. This would mean having two registry searches on for the 32 bit registry location and one for the 64 bit location. You can something like this
<util:RegistrySearch Id="IsSMOInstalledx86"
Root="HKLM"
Key="SOFTWARE\Microsoft\Microsoft SQL Server\SharedManagementObjects\CurrentVersion"
Value="Version"
Result="exists"
Variable="SMOInstalled"/>
<util:RegistrySearch Id="IsSMOInstalledx64"
After="IsSMOInstalledx86"
Condition="SMOInstalled = 0 AND VersionNT64"
Root="HKLM"
Key="SOFTWARE\Microsoft\Microsoft SQL Server\SharedManagementObjects\CurrentVersion"
Value="Version"
Win64="yes"
Result="exists"
Variable="SMOInstalled"/>
(Just as an extra gotcha, you can't use "NOT SMOInstalled" in your registry condition because just using PROPERTYNAME or NOT PROPERTYNAME in a condition actually evaluates whether the property is defined or not and doesn't actually evaluate the value of that property at all. See here for more info, specifically under the "Properties in Expressions" header.)

WiX - compare String with <property> in <?if ?> <? else ?> statement

Hey Guys hopefully somebody could help me with this problem. I am trying to compare the value of an Property with an String which is manually defined.
I am not sure if it should work like this here is my Code.
<Variable Name="VS2013Installed" />
<Variable Name="VS2015Installed" />
<!-- Should Search the Registry for the Keys -->
<!-- Searches for the Key of Visual Studio 2013 -->
<Property Id="VS2013" Secure="yes" >
<RegistrySearch Id="SEARCH_VS2010" Type="raw" Root="HKCR" Key="VisualStudio.accessor.12.0\shell\Open\ddeexec\Application" >
</RegistrySearch>
</Property>
<!-- Searches for the Key of Visual Studio 2015 -->
<Property Id="VS2015" Secure="yes" >
<RegistrySearch Id="SEARCH_VS2015" Type="raw" Root="HKCR" Key="VisualStudio.accessor.14.0\shell\Open\ddeexec\Application" >
</RegistrySearch>
</Property>
<!-- Should compare the value of the property with the String-->
<?if [VS2013] = "VisualStudio.12.0" ?>
<?define VS2013Installed= "1" ?>
<?else ?>
<?define VS2013Installed= "0" ?>
<?endif?>
<!-- Should compare the value of the property with the String-->
<?if [VS2015] = "VisualStudio.14.0" ?>
<?define VS2015Installed= "1" ?>
<?else ?>
<?define VS2015Installed= "0" ?>
<?endif?>
<!-- This Condition is only here to get an Message Window with the values of the variables-->
<Condition Message="$(var.VS2013Installed)$(var.VS2015Installed)">
<![CDATA[0 = 1 ]]>
</Condition>
As a result of the Condition I am getting: 0,0
WiX conditional compilation is for WiX variables. You want conditions on Windows Installer properties. It looks like you have a handle on setting properties and using property expressions; just make it all properties and conditions. (Your use of WiX define and var is fine, though.)
You are using the WiX Toolset to build a Windows Installer package (.msi file). A Windows Installer package is a relational database as you can see visually with tools like InstEd. The Windows Installer engine (msiexec) uses the database to perform standard and custom actions for an operation (install, repair, uninstall, etc) on a product. Actions can set, pass and retrieve data via Windows Installer properties. A property is usually referenced via its name in square brackets, e.g., [VS2015]. Except for WiX-provided custom action (they you might or might not use), everything that is happens at install-time is Windows Installer.
WiX variables are simply a way of avoiding repetition in your WiX source. They are "compiled away" when WiX builds the package. So, their values are fixed. WiX's conditional compilation (define, if, etc) are also compiled away at build-time.
In your code, it seems you expect to use a property value in a conditional compilation statement. Property values are not set until msiexec runs. So, you have find another way of using the information you are gathering with registry search. One way might be, if you have a Feature that supports VS2015 and another that supports 2013, is to enable or disable features based on expressions that reference the property values.
If you want to detect which versions of Visual Studio are installed then look at the WiX-supplied WixVSExtension and just use the properties it supplies.
http://wixtoolset.org/documentation/manual/v3/customactions/wixvsextension.html
and it does include VS 2013 and 2015.

Quicktime is installing when it is already installed

I have a WIX installer bundle that has QuickTime as a prereq. I trying to check a registry key to determine if it's already installed but it always comes back false.
The log shows...
[08B4:040C][2015-07-06T10:50:14]i000: Registry key not found. Key = 'HKEY_LOCAL_MACHINE\SOFTWARE\Clients\Media\QuickTime'
[08B4:040C][2015-07-06T10:50:14]i000: Setting numeric variable 'QuickTimeFound64' to value 0
[08B4:040C][2015-07-06T10:50:14]i000: Registry key not found. Key = 'HKEY_LOCAL_MACHINE\SOFTWARE\Clients\Media\QuickTime'
The registry is ...
The code is ...
<util:RegistrySearch Root="HKLM" Key="HKEY_LOCAL_MACHINE\SOFTWARE\Clients\Media\QuickTime" Result="exists" Variable="QuickTimeFound64" Win64="yes" />
<util:RegistrySearch Root="HKLM" Key="HKEY_LOCAL_MACHINE\SOFTWARE\Clients\Media\QuickTime" Result="exists" Variable="QuickTimeFound32" Win64="no" />
<Chain>
<PackageGroupRef Id="PackageGroup_NetFx35Redist"/>
<PackageGroupRef Id="PackageGroup_NetFx40Redist"/>
<PackageGroupRef Id="PackageGroup_SQLServer2012"/>
<ExePackage Id="Package_QuickTime" Cache="no" Compressed="$(var.Compressed)"
Description="Apple QuickTime 7" DownloadUrl="$(var.GuruDownloadRepo)/{2}"
SourceFile="..\Prerequisites\QuickTimeInstaller.exe"
Name="Prerequisites\QuickTimeInstaller.exe"
Permanent="yes" DisplayName="Apple QuickTime 7"
DetectCondition="QuickTimeFound64 AND QuickTimeFound32" />
I have tried including "Wow6432Node" in the 64bit path but it didn't make any difference.
Can anyone tell me why both of the searches are coming back as false?
Use
SOFTWARE\Clients\Media\QuickTime
instead of
HKEY_LOCAL_MACHINE\SOFTWARE\Clients\Media\QuickTime
because HKEY_LOCAL_MACHINE is specified in the Root attribute.

The Fragment element contains an unhandled extension element 'util:RegistrySearch'

Learning how to create Wix Booloader so that I can install .NET framework with my msi install package. Anyway I am stuck with an error for an unhandled extension element. Code is below
<?xml version="1.0" encoding="utf-8"?>
<!--
# This comment is generated by WixEdit, the specific commandline
# arguments for the WiX Toolset are stored here.
candleArgs: "<projectfile>" -ext WixBalExtension
lightArgs: "<projectname>.wixobj" -ext WixBalExtension
-->
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Bundle UpgradeCode="80B0ECBE-CAAE-4B6A-9705-49F0232B0C24"
Version="0.0.1">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
<Chain>
<PackageGroupRef Id="Netfx45" />
</Chain>
</Bundle>
<Fragment>
<util:RegistrySearch Root="HKLM"
Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v4\Full"
Value="Version"
Variable="Netfx4FullVersion" />
<util:RegistrySearch Root="HKLM"
Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v4\Full"
Value="Version"
Variable="Netfx4x64FullVersion"
Win64="yes" />
<!-- .NET 4.5 only installed if Vista or higher AND it's not already installed-->
<!-- .NET 4.5 only installed if Vista or higher AND it's not already installed-->
<PackageGroup Id="Netfx45">
<ExePackage Id="Netfx45"
Cache="no"
Compressed="yes"
PerMachine="yes"
Permanent="yes"
Vital="yes"
InstallCommand="/q"
SourceFile="C:\Users\ProRip\Downloads\dotnetfx45_full_x86_x64.exe"
DetectCondition="(Netfx4FullVersion="4.5.50709") AND (NOT VersionNT64 OR (Netfx4x64FullVersion="4.5.50709"))"
InstallCondition="(VersionNT >= v6.0 OR VersionNT64 >= v6.0) AND (NOT (Netfx4FullVersion="4.5.50709" OR Netfx4x64FullVersion="4.5.50709"))" />
</PackageGroup>
</Fragment>
Error message is
error CNDL0200 : The Fragment element contains an unhandled extension element 'util:RegistrySearch'. Please ensure that the extension for elements in the 'http://schemas.microsoft.com/wix/UtilExtension' namespace has been provided.
error CNDL0200 : The Fragment element contains an unhandled extension element 'util:RegistrySearch'. Please ensure that the extension for elements in the 'http://schemas.microsoft.com/wix/UtilExtension' namespace has been provided
Can anyone please explain what my error is I have included the correct namespace and I can't see a reason for the error!
The WiX extension for the namespace xmlns:util="http://schemas.microsoft.com/wix/UtilExtension is provided by a dll named WixUtilExtension (this assuming you are using Visual Studio). Right-click on the References node in your project and add a reference to the WixUtilExtension dll.

Wix "Product element contains an unexpected child element util: RegistrySearch" error message on launch condition

I am totally new to Wix and I have been tasked with this.
The installer should prompt the message "Application requires Reportviewer". It should check if reportViewer is installed and if not throw the message at the beginning of installation itself.
This is what I am trying to do (randomly trying things out as I still do not understand the details)
<Condition Message="This application requires ReportViewer.">
<![CDATA[ReportViewerV10 OR ReportViewerWow64V10]]>
</Condition>
<util:RegistrySearch
Root="HKLM"
Key="SOFTWARE\Microsoft\ReportViewer\v10.0"
Value="Install"
Variable="ReportViewerV10"
Win64="yes"
/>
<util:RegistrySearch
Root="HKLM"
Key="SOFTWARE\Wow6432Node\Microsoft\ReportViewer\v10.0"
Value="Install"
Variable="ReportViewerWow64V10"
Win64="yes"
/>
You need to add a reference to http://schemas.microsoft.com/wix/UtilExtension in your main container tag in WIX project to refer util:RegistrySearch.
Document Should Look Like
<?xml version="1.0"?>
<Include xmlns="http://schemas.microsoft.com/wix/2003/01/wi">
.
.
.
</Include>
OR
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi">
.
.
.
</Wix>
You can keep this utility call in a Bundle tag or a Fragment tag only.
Refer RegistrySearch Element (Util Extension) Documentation for more details on this.
Refer WIX Documenation for more ideas.