WiX 'Bundle' 'ExePackage' 'DetectCondition' is always false - visual-studio-2010

I am trying to create a WiX bundle that installs the .NET Framework 4.0 before my MSI installer. I inspected the log file for my bootstrapper using the command line argument \l log.txt and discovered that the ExePackage::DetectCondition is always evaluating to false.
I am including WixNetFxExtension.dll as a reference in my Visual Studio 2010 Windows Installer XML Bootstrapper project.
I am including the NetFxExtension namespace:
<?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:bal="http://schemas.microsoft.com/wix/BalExtension"
xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">
Providing the basic bundle framework:
<Bundle Name="RSA Bootstrapper"
...
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
...
<Chain>
<PackageGroupRef Id="NET40" />
<PackageGroupRef Id="RSA_Application" />
</Chain>
</Bundle>
...
I am including the <PropertyRef Id="NETFRAMEWORK40FULL" /> in the fragment and then going on to define the ExePackage for .NET Framework 4.0 (NET40):
<Fragment>
<PropertyRef Id="NETFRAMEWORK40FULL" />
<PackageGroup Id="NET40">
<ExePackage SourceFile="dotNetFx40_Full_x86_x64.exe"
Compressed="yes"
Cache="yes"
DetectCondition="NETFRAMEWORK40FULL"
InstallCommand="/norestart /passive /showrmui /ACTION=Install"
Permanent="yes"
InstallCondition="NOT NETFRAMEWORK40FULL"
Vital="yes" >
<ExitCode Value="0" Behavior="success" />
<ExitCode Value="1641" Behavior="scheduleReboot" />
<ExitCode Value="3010" Behavior="scheduleReboot" />
<ExitCode Behavior="error" /> <!-- Everything else is an error -->
</ExePackage>
...
I have also checked the Visual Studio build output to confirm that the WixNetFxExtension.dll is referenced correctly:
C:\Program Files (x86)\WiX Toolset v3.7\bin\Light.exe ... -ext "C:\Program Files (x86)\WiX Toolset v3.7\bin\WixNetFxExtension.dll"
The problem is with the DetectCondition property. No matter what I set it to, it evaluates to false.
Thinking that maybe the NETFRAMEWORK40FULL reference cannot be trusted, I tried using this instead:
<Fragment>
<Variable Name="isInstalled"
Type="numeric"
Value="0"
Persisted="yes"
bal:Overridable="yes"/>
<util:RegistrySearch Id="FindInstallKey"
Root="HKLM" Key="SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"
Value="Install"
Result="exists"
Variable="InstallKeyExists" />
<util:RegistrySearch
Root="HKLM" Key="SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"
Value="Install"
Variable="isInstalled"
After="FindInstallKey"
Condition="InstallKeyExists = true"
Format="raw" />
</Fragment>
Setting DetectCondition="isInstalled" or DetectCondition="isInstalled = true" always evaluates to false. Even setting DetectCondition="true" always evaluates to false!
Here is a log snippet of what I am talking about, with DetectCondition="true"
[16A0:17B4][2013-02-13T13:01:43]i001: Burn v3.7.1224.0, Windows v6.1 (Build 7601: Service Pack 1), path: C:\Users\lalic\Documents\Visual Studio 2010\Projects\RSA Preset\Bootstrapper\bin\Release\Bootstrapper.exe, cmdline: '/l log.txt -burn.unelevated BurnPipe.{33090847-CC78-445B-BAAA-564B840B7E8E} {38F95C6A-EC0F-4402-951B-FABFC5827CB6} 6296'
[16A0:17B4][2013-02-13T13:01:43]i000: Setting string variable 'WixBundleLog' to value 'C:\Users\lalic\Documents\Visual Studio 2010\Projects\RSA Preset\Bootstrapper\bin\Release\log.txt'
[16A0:17B4][2013-02-13T13:01:43]i000: Setting string variable 'WixBundleOriginalSource' to value 'C:\Users\lalic\Documents\Visual Studio 2010\Projects\RSA Preset\Bootstrapper\bin\Release\Bootstrapper.exe'
[16A0:17B4][2013-02-13T13:01:43]i052: Condition '((VersionNT = v5.1) AND (ServicePackLevel >= 3)) OR ((VersionNT = v5.2) AND (ServicePackLevel >= 2)) OR ((VersionNT = v6.0) AND (ServicePackLevel >= 1)) OR (VersionNT >= v6.1)' evaluates to true.
[16A0:17B4][2013-02-13T13:01:43]i000: Setting string variable 'WixBundleName' to value 'RSA Bootstrapper'
[16A0:17B4][2013-02-13T13:01:43]i100: Detect begin, 2 packages
[16A0:17B4][2013-02-13T13:01:43]i052: Condition 'true' evaluates to false.
[16A0:17B4][2013-02-13T13:01:43]i103: Detected related package: {D431417D-F0AC-4CFB-8E25-E27F5B8101D9}, scope: PerMachine, version: 2.1.15.0, language: 0 operation: MajorUpgrade
[16A0:17B4][2013-02-13T13:01:43]i101: Detected package: dotNetFx40_Full_x86_x64.exe, state: Absent, cached: None
[16A0:17B4][2013-02-13T13:01:43]i101: Detected package: RSA_Preset.msi, state: Absent, cached: None
[16A0:17B4][2013-02-13T13:01:43]i199: Detect complete, result: 0x0
[16A0:17B4][2013-02-13T13:02:04]i200: Plan begin, 2 packages, action: Install
[16A0:17B4][2013-02-13T13:02:04]i052: Condition 'NOT NETFRAMEWORK40FULL' evaluates to true.
Specifically,
i052: Condition 'true' evaluates to false.
and actually Condition 'NOT NETFRAMEWORK40FULL' evaluates to true. even though I have .NET 4.0 Full installed and can manually find the .NET 4.0 entry in my registry, both in the usual spot and under HKLM\SOFTWARE\Wow6432Node (I am on a 64 bit system).
Am I missing something? Why doesn't DetectCondition work for me? The project compiles, runs, deploys the payload(s) and otherwise works fine.

<PropertyRef Id="NETFRAMEWORK40FULL" /> is a reference to an MSI property but you're creating a bundle. Bundles have variables that are distinct from MSI properties, though Burn itself provides a number of bundle variables that mimic those that MSI provides.
That said, WixNetFxExtension provides package groups for the 4.0 NetFx installers. You can replace all that with a simple <PackageGroupRef Id="NetFx40Redist" />.

Variables like NETFRAMEWORK40FULL are MSI variables, you cannot use them in Bundles.
I have successfully embedded the .NET Framework 4.0 Client Version within my bundle. Conditions variables resolved from the Registry.
Notice the syntax "<<" (which translates to <<) in DetectCondition attribute. This page may help http://wix.tramontana.co.hu/tutorial/com-expression-syntax-miscellanea/expression-syntax
<?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:util="http://schemas.microsoft.com/wix/UtilExtension"
xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">
<Bundle
Name="My Program Name"
Version="1.2.0"
Manufacturer="SUSU"
UpgradeCode="some-guid">
<Chain>
<PackageGroupRef Id="Netfx4"/>
<MsiPackage Id="MyProgramInstaller" SourceFile="product.msi" Compressed="yes"/>
</Chain>
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense">
<bal:WixStandardBootstrapperApplication
LicenseFile="license.rtf"
ShowVersion="yes"
/>
</BootstrapperApplicationRef>
</Bundle>
<Fragment>
<util:RegistrySearch Root="HKLM" Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v4\Client" Value="Version"
Variable="Netfx4ClientVersion" />
<util:RegistrySearch Root="HKLM" Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v4\Client" Value="Version"
Variable="Netfx4x64ClientVersion" Win64="yes" />
<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"/>
<PackageGroup Id="Netfx4">
<ExePackage
Id="Netfx4"
Cache="no"
Compressed="yes"
PerMachine="yes"
Permanent="yes"
Vital="yes"
SourceFile="c:\Downloads\dotNetFx40_Client_x86_x64.exe"
InstallCommand="/q"
DetectCondition="(Netfx4FullVersion << "4") OR (Netfx4ClientVersion << "4") OR (Netfx4x64ClientVersion << "4") OR (Netfx4x64FullVersion << "4")"
/>
</PackageGroup>
</Fragment>
</Wix>

Related

How to run exe inside msi?

Kind time of the day! I'm working on creating an msi installer using the wix toolkit. It was required to run exe from under the msi installer. Here is my code:
<Binary Id="JDK_EXE" src="..\..\jdk\jdk-6u45-windows-i586.exe"/>
<CustomAction Id="RunJavaJDKInstall"
BinaryKey="JDK_EXE"
ExeCommand=""
Return="check"/>
<InstallExecuteSequence>
<Custom Action ="RunJavaJDKInstall" After="InstallInitialize"></Custom>
</InstallExecuteSequence>
The question is what to write in the ExeCommand tag to run jdk-6u45-windows-i586.exe on execution?
You cant make in msı project but you can make it with wix bootstrapper project like this.
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
<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" />
<Chain>
<!-- <PackageGroupRef Id="Net47"/>-->
<ExePackage Id="Net45" Name="Microsoft .NET Framework 4.5.1 Setup" Cache="no" Compressed="yes" PerMachine="yes" Permanent="yes" Vital="yes" InstallCommand="/q"
SourceFile=".\prerequisites\NNDP47-KB3186497-x86-x64-AllOS-ENU.exe"
DetectCondition="(Net4FullVersion = "4.5.50938") AND (NOT VersionNT64 OR (Net4x64FullVersion = "4.5.50938"))"
InstallCondition="(VersionNT >= v6.0 OR VersionNT64 >= v6.0) AND (NOT (Net4FullVersion = "4.5.50938" OR Net4x64FullVersion = "4.5.50938"))"/>
<ExePackage Id="Netfx4Full"
DisplayName="Microsoft .NET Framework 4.0"
Compressed="yes"
Cache="yes"
PerMachine="yes"
Permanent="yes"
Protocol="netfx4"
Vital="yes"
SourceFile=".\prerequisites\NNDP47-KB3186497-x86-x64-AllOS-ENU.exe"
InstallCommand="/passive /norestart"
DetectCondition="(Net4FullVersion = "4.5.50938") AND (NOT VersionNT64 OR (Net4x64FullVersion = "4.5.50938"))"
InstallCondition="(VersionNT < v6.0 OR VersionNT64 < v6.0) AND (NOT (Net4FullVersion OR Net4x64FullVersion))" />
<RollbackBoundary />
<!-- <PackageGroupRef Id="SQLExpressCE"/> Install Application NetVersion >= 460798-->
<MsiPackage Id="MyApplication" SourceFile="$(var.SetupProject1.TargetPath)" DisplayInternalUI="yes" Compressed="yes" Vital="yes"/>
</Chain>
</Bundle>

Wix to remove previous version that was installed with Bootstrapper from control panel

I've got "ABC 10.1" program version installed on computer allready and I would like to remove it on each newer ABC.msi installation (for example when ABC 10.2 is going to be installed).
So far I've used a BOOTSTRAPPER to install new versions and it worked like a charm (the previous version was uninstalled and removed from the control panel and newest was appearing in the control panel).
Right now I would like to use ABC.msi for installation and to not use the BOOTSTRAPPER, but when I use ABC.msi installer the previous one is not being removed from the control panel and I have two "ABCs" 10.1 and 10.2 versions in the control panel.
How can I remove ABC previous version that was installed by BOOTSTRAPPER during newest ABC.msi installation (and avoid duplicating ABC in Control Panel)?
Bundle.wxs
<Bundle
Name="$(var.ProductName)"
Version="$(var.ShowVersion)"
Manufacturer="ABC"
UpgradeCode="33312c8d-64f1-4a04-a98e-4aa692de6aaf"
IconSourceFile="$(var.BaseDir)\Setup\UI\ABC.ico"
Condition="((VersionNT = v6.1 AND ServicePackLevel >= 1) OR (VersionNT > v6.1)) AND (WixBundleInstalled = 0)">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense">
<bal:WixStandardBootstrapperApplication
LicenseFile="$(var.BaseDir)\Setup\UI\License.rtf"
LogoFile="$(var.BaseDir)\Setup\UI\OticonAppIcon.png"
SuppressOptionsUI="yes"
ShowVersion="yes"/>
</BootstrapperApplicationRef>
<Chain>
<!-- Install .Net 4.6.1 -->
<PackageGroupRef Id='NetFx461Redist'/>
<!-- my packages to install -->
<PackageGroupRef Id="InstallerPackages" />
</Chain>
</Bundle>
<Fragment>
<PackageGroup Id ="InstallerPackages" >
<MsiPackage SourceFile="$(var.OutDir)\ABC.MSI" />
<MsiPackage SourceFile="$(var.OutDir)\DatabaseInstallerABC.msi" />
</PackageGroup>
</Fragment>
productABC.wxs (the file that is creating ABC.msi) is as following:
<?xml version="1.0" encoding="UTF-8"?>
<?include .\defines.wxi ?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension" xmlns:fire="http://schemas.microsoft.com/wix/FirewallExtension" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Product Id="$(var.ProductCode)"
Codepage="1252" Language="1033"
Manufacturer="ABC" Name="$(var.ProductName)"
UpgradeCode="{3338CE6B-D733-41AF-830B-DCAFE2E0CD58}"
Version="$(var.ProductVersion)">
<Package Id="*"
Compressed="yes"
InstallerVersion="300"
Languages="1033"
Manufacturer="ABC"
Platform="x86" />
<Media Id="1"
Cabinet="media1.cab"
EmbedCab="yes" />
----some directories and components----
<MajorUpgrade
Schedule="afterInstallInitialize"
DowngradeErrorMessage="A later version of [ProductName] is already installed. Setup will now exit."
AllowSameVersionUpgrades="yes"/>
<InstallExecuteSequence>
<LaunchConditions After="AppSearch" />
<Custom Action="SetTargetDir" Before="CostFinalize"></Custom>
<Custom Action="SaveTargetDir" After="InstallValidate"></Custom>
</InstallExecuteSequence>
<WixVariable Id="WixUILicenseRtf" Value="$(var.BaseDir)\Setup\UI\License.rtf" />
<WixVariable Id="WixUIBannerBmp" Value="$(var.BaseDir)\Setup\UI\bannrbmp.bmp" />
<WixVariable Id="WixUIDialogBmp" Value="$(var.BaseDir)\Setup\UI\ABCbackground.bmp" />
</Product>
</Wix>
Generic answer: The wix bootstrapper is what writes the entry in the Control Panel for your "ABC 10.1" release. In order to remove that, your 10.2 release will need to have a custom action tell the previous bundle to uninstall itself ("previous-cached-bundle.exe /silent /uninstall" or something similar). Now, whether you tell the old bundle to remove itself first, or you allow your MSI to upgrade first is up to your own requirements.

Detect if visual studio 2010 and 2013 re-distributables are present using wix burn

I've created an installer which requires Visual Studio re-distributables 2010 and 2013. My installer has been created using Wix Burn Bootstrapper. I tried to add the re-distributables to my bundle.wxs using the following lines.
<Fragment>
<util:FileSearch Id="MFC120_Version_x86"
Variable="MFC120_Version_x86" Path="[SystemFolder]mfc120.dll"
Result="version"/>
<PackageGroup Id="redist_vc120">
<ExePackage Id="vc120" Cache="yes" PerMachine="yes" Permanent="yes" Vital="yes" Compressed="yes"
SourceFile="vcredist_x86.exe"
Name="redist\vc120\vcredist_x86.exe"
InstallCommand="/quiet /norestart"
InstallCondition="(NOT MFC120_Version_x86 >= v12.0.21005.1) OR NOT MFC120_Version_x86"
Protocol="burn"
/>
</PackageGroup>
</Fragment>
<Fragment>
<util:FileSearch Id="MFC100_Version_x86"
Variable="MFC100_Version_x86" Path="[SystemFolder]mfc100.dll"
Result="version"/>
<PackageGroup Id="redist_vc100">
<ExePackage Id="vc100" Cache="yes" PerMachine="yes" Permanent="yes" Vital="yes" Compressed="yes"
SourceFile="vcredist_x86.exe"
Name="redist\vc100\vcredist_x86.exe"
InstallCommand="/quiet /norestart"
InstallCondition="(NOT MFC100_Version_x86 >= v10.0.30319.1) OR NOT MFC100_Version_x86"
Protocol="burn"
/>
</PackageGroup>
</Fragment>
<Fragment>
<PackageGroup Id="redist">
<PackageGroupRef Id="redist_vc110"/>
<PackageGroupRef Id="redist_vc120"/>
</PackageGroup>
</Fragment>
But it doesn't properly detect them and installer terminates. When I go see the Programs and Features, there are no installed packages. What am I doing wrong here? How to properly detect the presence of these and install them? I don't want to use the merge element method as I want to do this with my Bundle.wxs itself without creating a separate WIX project for these re-distributables. Please advice.

Merge two MSI into One using WIX Bootsrapper

In My application there are 2 msi installers.one is vendor supplied and cannot be modified, the other is a MSI file which i have generated using VS2010 setup and deployment.
I combined these two into one using WIX Bootstrapper,when i build this application it gives two MSIs and One Bootstrapper exe, obviously when i Click Bootstrapper exe it installs other two MSIs in a sequential manner, but the problem is I just want to give this single Bootstrapper exe to customer, but it needs other two MSIs also ,Is there any other way to do it? please find the code below..
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Bundle Name="SoftWritersInstaller_Package" Version="1.0.0.0" Manufacturer="Microsoft" UpgradeCode="86431df1-94cc-433a-9885-af19bca9b5d3">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
<Chain >
<!-- TODO: Define the list of chained packages. -->
<!-- <MsiPackage SourceFile="path\to\your.msi" /> -->
<PackageGroupRef Id="Netfx4Full"/>
<MsiPackage Id="F_VB_AGENT" SourceFile=".\VBandMsi\Framewrk with Agent.msi" Compressed="no" EnableFeatureSelection="yes" DisplayInternalUI="yes" ></MsiPackage>
<MsiPackage Id="FVBAgent.Net" SourceFile=".\VBandMsi\.FDotNet.Setup.msi" Compressed="no" EnableFeatureSelection="yes" DisplayInternalUI="yes" />
</Chain>
</Bundle>
<Fragment>
<!-- Check for .NET 4.0 -->
<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"
/>
<PackageGroup Id="Netfx4Full">
<ExePackage Id="Netfx4Full"
DisplayName="Microsoft .NET Framework 4.0"
Compressed="yes"
Cache="yes"
PerMachine="yes"
Permanent="yes"
Protocol="netfx4"
Vital="yes"
SourceFile=".\dotNetFx40_Full_x86_x64.exe"
InstallCommand="/passive /norestart"
DetectCondition="Netfx4FullVersion AND (NOT VersionNT64 OR Netfx4x64FullVersion)" />
</PackageGroup>
</Fragment>
</Wix>

WiX Bundle bal:condition - util:RegistrySearch variable always false

I want my install to fail if a third-party software element is not installed. I added a Fragment with a util:RegistrySearch and a bal:Condition to the Bundle, 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 for Key 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 False
ThirdPartyCOMLibraryInstalled <> 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>
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 the Bundle element.
Add a RegistrySearchRef element in the Bundle element to reference the RegistrySearch in the Fragment. You will also need to give the RegistrySearch and Id 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.

Resources