WiX Bundle bal:condition - util:RegistrySearch variable always false
The root issue is that the RegistrySearch
is in a separate Fragment
that never gets referenced. Because nothing in the Fragment
gets referenced the linker "optimizes away" the contents of the Fragment
and the search is not included in your Bundle
.
Aside: you could argue that the fact that there is a reference to the variable mentioned in the search in the
Condition
that the linker should be able to figure out that the search is necessary. However, that doesn't work out in all cases.
Fortunately, the solution is quite simple! You even have to choose from one of two:
- Move the
RegistrySearch
element to theBundle
element. - Add a
RegistrySearchRef
element in theBundle
element to reference theRegistrySearch
in theFragment
. You will also need to give theRegistrySearch
andId
attribute.
Personally, I like option two and I would probably even move the Condition
into the Fragment
as well to group all that stuff together. Something akin to:
<Bundle ...>
<util:RegistrySearchRef Id='SearchForThirdParty' />
...
</Bundle>
<Fragment>
<util:RegistrySearch
Id='SearchForThirdParty'
Variable="ThirdPartyCOMLibraryInstalled"
Result="exists"
Root="HKLM"
Key="SOFTWARE\Classes\ThirdPartyId.Server\CLSID"/>
<bal:Condition Message="ThirdParty Application COM Library Required. Please (re)install ThirdParty Application and ensure 'Windows API' and '.Net Components' are installed.">ThirdPartyCOMLibraryInstalled</bal:Condition>
</Fragment>
</Wix>
That should do it.
Pauli Price
I consider programming to be a craft, one to which I aspire to mastery. I’m also pragmatic, so while my typical approach is ‘first get it working, then make it efficient,’ I’m well aware that sometimes, for some code, “then” will never come. Current Interests: Javascript web application development My recent focus has been javascript web development, primarily Node on the back end and Angularjs or React on the front. . Web Application Infrastructure / DevOps / Build Process Engineering I've enjoy working with Docker, Terraform, Ansible, Continuous Integration and Continuous Deployment automation, while deploying personal projects.
Updated on June 05, 2022Comments
-
Pauli Price almost 2 years
I want my install to fail if a third-party software element is not installed. I added a
Fragment
with autil:RegistrySearch
and abal:Condition
to theBundle
, but I can't get it to work.ThirdPartyCOMLibraryInstalled
never evaluates to true. I've confirmed that the key exists, and the value I use forKey
is correct - I copy/pasted the name from the selected key in regedit. There aren't any errors in the log.I'm building the installer with WiXTools 3.7 in Visual Studio 2012 on Windows 7 64-bit and testing on both Windows XP SP3 and Windows 7 64-bit.
Searching online for other examples for
util:RegistrySearch
I ran across the following alternative forms for the condition test expression.ThirdPartyCOMLibraryInstalled = 0
- always FalseThirdPartyCOMLibraryInstalled <> 1
- always True
Here is the
Bundle
code:<?xml version="1.0" encoding="UTF-8"?> <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension" xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"> <Bundle Name="!(bind.packageName.MyApp)" Version="!(bind.packageVersion.MyApp)" Manufacturer="!(bind.packageManufacturer.MyApp)" UpgradeCode="a07ce1d5-a7ed-4d89-a7ee-fb13a5dd69ba" Copyright="Copyright (c) 2013 [Bundle/@Manufacturer]. All rights reserved." IconSourceFile="$(var.My_Application1.ProjectDir)MyCo.ico"> <bal:Condition Message="ThirdParty Application COM Library Required. Please (re)install ThirdParty Application and ensure 'Windows API' and '.NET Components' are installed." >ThirdPartyCOMLibraryInstalled</bal:Condition> <Variable Name="InstallFolder" Type="string" Value="[ProgramFilesFolder]MyCo Systems\My_Application\"/> <BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.HyperlinkLicense" > <bal:WixStandardBootstrapperApplication ThemeFile="Resources\HyperlinkTheme.xml" LaunchTarget="[InstallFolder]My_Application.exe" LocalizationFile="Resources\HyperlinkTheme.wxl" SuppressRepair="yes" SuppressOptionsUI="yes" LicenseUrl="" LogoFile="Resources/MyCoLogoWt64.png" /> </BootstrapperApplicationRef> <Chain> <PackageGroupRef Id="NetFx40Redist"/> <MsiPackage Id ="MyApp" Vital="yes" Name="My Application" SourceFile="$(var.MyApp_Install.TargetDir)MyApp_Install.msi"> <MsiProperty Name="INSTALLLOCATION" Value="[InstallFolder]" /> </MsiPackage> </Chain> </Bundle> <Fragment> <util:RegistrySearch Variable="ThirdPartyCOMLibraryInstalled" Result="exists" Root="HKLM" Key="SOFTWARE\Classes\ThirdPartyId.Server\CLSID"/> </Fragment> </Wix>
-
Pauli Price about 11 yearsThat works exactly. Thank you. I'd be happy to have this posted on the WiX documentation as one of the 'How To Guides' i.e. "Block bootstrapper installation based on a missing registry key" What can I do to make that happen?
-
Rob Mensching about 11 yearsSounds good. To add help, send a pull request against the wix38 branch with changes to files under:
src\chm\html
. Code is at wix.codeplex.com