WiX Burn: Reading LaunchTarget from Registry - wix

I'm new with WiX, and I'm trying to have my Bootstrapper launch my installed application when it completes. To accomplish this, I'm using
<Variable Name="LaunchTarget" Value="path_to_exe"/>
However, it is not easy for me to get the path to the executable. The reason for this is because I'm using <Chain> to install some pre-requisites and then an msi that actually installs my exe.
So to do this, the msi is writting the path to a known location in the registry, and then the bootstrapper reads it and uses it.
The problem is that when the bootstrapper reads the registry, the msi hasn't run yet, so it is unable to run the executable at the end.
Here's my WiX, if it helps:
<?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">
<Bundle Name="My Installation" UpgradeCode="a8964402-f3fc-4878-aafd-31ecda6b685e" Version="1.0.0.0">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense">
<bal:WixStandardBootstrapperApplication LicenseFile="EULA.rtf"
ThemeFile="theme.xml"
SuppressOptionsUI="yes" />
</BootstrapperApplicationRef>
<Chain>
<PackageGroupRef Id="NetFx40Redist"/>
<ExePackage Id="OpenSSL" SourceFile="pre-requesite.exe" />
<MsiPackage Id="myInstall" SourceFile="mySetup.msi" />
</Chain>
<util:RegistrySearch Root="HKLM"
Key="Software\myProgram"
Value="myEXEPath"
Variable="myEXEPath"
Result="value"
Format="raw" />
<Variable Name="LaunchTarget" Value="[myEXEPath]"/>
</Bundle>
</Wix>
So, in short, I'm trying to have the RegistrySearch run AFTER the MsiPackage installs. Can this be done? If not, what alternatives do I have?
As I side note, if I manually fill in the registry value before installation, everything works fine. This means that besides the order things are running in, everything is working fine.

RegistrySearches run during the Detect operation. Custom BAs could run Detect after Apply, but that's not really an option since you're using the WixStandardBootstrapperApplication.
Lucky for you, WiX v3.9 added support for running the LaunchTarget already elevated, with the requirement that the path to the target .exe be in the registry under HKLM. So you would do this:
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense">
<bal:WixStandardBootstrapperApplication LicenseFile="EULA.rtf"
ThemeFile="theme.xml"
SuppressOptionsUI="yes"
LaunchTargetElevatedId="MyAEEId" />
</BootstrapperApplicationRef>
<ApprovedExeForElevation Id="MyAEEId"
Key="Software\myProgram" Value="myEXEPath" />
Edit:
It looks like you are required to set LaunchTarget as well. Why doesn't your bundle know where it will be? You can just put in gibberish for LaunchTarget (WixStdBA will try the registry location first), but can't you use built-in variables and/or MsiProperty elements to locate the exe?

Related

Wix Bootstrap prevent temp directory use

I have builded "HelloWord" installer with the Bootstrapper Project for Wix v3 project type.
My bundle.wxs is
<?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">
<Bundle Name="Bundle_name"
Version="1.0.0.0"
Manufacturer="Producter"
UpgradeCode="C82A383C-751A-43B8-90BF-A250F7BC2863"
IconSourceFile="..\WpfForms\Assets\my_lovely.ico" >
<BootstrapperApplicationRef Id="ManagedBootstrapperApplicationHost">
<Payload SourceFile="..\WpfForms\BootstrapperCore.config"/>
<Payload SourceFile="..\WpfForms\bin\Debug\WpfForms.dll"/>
<Payload SourceFile="..\WpfForms\bin\Debug\GalaSoft.MvvmLight.dll"/>
<!--<Payload SourceFile="..\WpfForms\bin\Debug\Microsoft.Practices.ServiceLocation.dll"/>
<Payload SourceFile="..\WpfForms\bin\Debug\Microsoft.WindowsAPICodePack.dll"/>
<Payload SourceFile="..\WpfForms\bin\Debug\Microsoft.WindowsAPICodePack.Shell.dll"/>-->
<Payload SourceFile="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.ServiceProcess.dll"/>
<Payload SourceFile="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Configuration.Install.dll"/>
<Payload SourceFile="C:\Program Files (x86)\WiX Toolset v3.11\SDK\Microsoft.Deployment.WindowsInstaller.dll"/>
</BootstrapperApplicationRef>
<Chain>
<PackageGroupRef Id='Netfx4Full'/>
<MsiPackage SourceFile="..\WixSetupProject\bin\Debug\WixSetupProject.msi" Id="InstallationPackageId" Cache="yes" Visible="no"/>
</Chain>
</Bundle>
<Fragment>
<WixVariable Id="WixMbaPrereqPackageId" Value="Netfx4Full" />
<WixVariable Id="WixMbaPrereqLicenseUrl" Value="NetfxLicense.rtf" />
<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" Cache="no" Compressed="yes" PerMachine="yes" Permanent="yes" Vital="yes" Name="DotNet_4"
SourceFile="../WixBootstrapper/DotNet/NDP462-KB3151800-x86-x64-AllOS-ENU.exe"
DownloadUrl="http://go.microsoft.com/fwlink/?LinkId=164193"
DetectCondition="Netfx4FullVersion AND (NOT VersionNT64 OR Netfx4x64FullVersion)" />
</PackageGroup>
</Fragment>
</Wix>
My problem is that the work station's antivirus configured to block any activity from temp directories and the builded installer.exe make copy of itself as "C:\Windows\Temp{74EA5B2A-DA46-4B3F-A8E9-4FCEC4B4523C}.cr\WixBootstrapper.exe" and run it by default. So it get locked by antivirus so instalation is over on start.
Do somebody know how can i prevent WiX components from create a cache or something in temp directories and set to run any nested executable and themselfs from the curent folder, not from the temp?
After checking Windows's group policy settings this turned out to be
an anti-virus blocking problem.
Group Policy?: Does the log contain something like this:
Error 0x800704ec: Failed to launch clean room process: "C:\WINDOWS\Temp\{AB10C981-0D7D-4AA6-857F-CC37696DB4BE}\.cr\Bundle.exe" -burn.clean.room="C:\Test\Bundle.exe" -burn.filehandle.attached=652 -burn.filehandle.self=656 -log "C:\Test\bundle.log"
Error 0x800704ec: Failed to run untrusted mode.
Or does it say something else? There is a group policy that can cause similar issues. See WiX issue 5856.
Anti-Virus Grace Period?: If you are administrator, there should be a possiblity to get a temporary grace period from your anti virus I would think. So you can perform your testing. I would give your own support desk a call first and then hit the Kaspersky user forums if unsuccessful. Perhaps you have a Kaspersky support agreement with priority support available?
False Positives: I also insist that you upload your binaries to virustotal.com to test for false positives. That you should do no matter what. Antivirus Whitelisting Pains by Bogdan Mitrache.
False positives can actually be worse than actual malware at times (so far as the malware isn't devastating)
because you cannot just tell the user to rebuild their machine(s). Instead you actually have
to fix the problem for them in a general sense. Not only does the user have a problem to fix, you have one as the vendor as well. How do you whitelist your product with 60+ anti-malware suites? You try virustotal.com first I think (not affiliated) - to check if you actually have such a problem.

WiX Bundle bal:condition - util:RegistrySearch - Not working

A similar post is up here but I cant get mine working
WiX Bundle bal:condition - util:RegistrySearch variable always false
Sir, I am struggling get this exact thing working. "Version" is set to 0 when Registry key is absent and to 1 when key is present. Either cases my bundle still gets installed.
I am using VS 2015 and Wix 3.10. Pls can you help.
<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">
<Bundle Name="XXX"
Version="XXX"
Manufacturer="XXX"
UpgradeCode="XXX"
IconSourceFile="XXX"
Copyright="XXX" >
<util:RegistrySearchRef Id='SearchForMyIns' />
<BootstrapperApplicationRef Id="ManagedBootstrapperApplicationHost">
...
</BootstrapperApplicationRef>
<Chain>
<PackageGroupRef Id='NetFx40Web' />
<MsiPackage SourceFile="$(var.DummyInstaller.TargetDir)\DummyInstaller.msi" DisplayName="Dummy Conditioning" />
</Chain>
</Bundle>
<Fragment>
<util:RegistrySearch
Id='SearchForMyInst'
Variable="Version"
Result="exists"
Root="HKLM"
Key="SOFTWARE\MyInst"
Win64="yes" />
<bal:Condition Message="ThirdParty Application Required.">Version</bal:Condition>
</Fragment>
</Wix>
The Bal:Condition doesn't evaluate if you are using MBA. Check the following link
http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/Wix-Burn-Bundle-condition-does-not-work-if-using-MBA-td7581757.html
Change
<BootstrapperApplicationRef Id="ManagedBootstrapperApplicationHost">
to
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense">
You will see Bal:Condition working
The reason this is always installing for you is that
<bal:Condition Message="messagehere">Version</bal:Condition>
will evaluate the existance of Version not the value of Version. Since your registry search is on exists, Version is always defined and thus the condition always passes. (I believe this is because all registry search variables are implicitly string variables)
If you add "Version = 1" then your installation should only continue when your registry search does find what you're looking for.
I would also like to point out a particularly nasty pitfall of this type of condition. What happens if a user installs your bundle then decides they don't need your bundle or the third party program anymore and they uninstall them both but they uninstall the third party program first?
Your installer will be unable to uninstall because when it tries to run it will fail the bal:Condition every time since the third party program is no longer present on the system.
To solve this behaviour you should add "OR WixBundleInstalled" to your bal:Condition.

How do I use burn's new ability to ability to launch an elevated process after installation is complete?

The current set of samples on how to use wix's new ability to run an elevated process through the engine is very sparse, if it exists at all. From the WIP and the schema docs, I can see that I need a minimum of the following:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension">
<Bundle Name="..." Version="1.0.0.0" Manufacturer="..." UpgradeCode="*">
<BootstrapperApplicationRef
Id="WixStandardBootstrapperApplication.RtfLicense">
<bal:WixStandardBootstrapperApplication
LaunchTargetElevatedId="LaunchElevatedInstallProc"
LaunchArguments="/myarg=1"
LicenseFile="license.rtf" />
</BootstrapperApplicationRef>
<ApprovedExeForElevation
Id="LaunchElevatedInstallProc"
Key="SOFTWARE\Company\Product"
Value="PathToExeDeliveredByMSI" />
<Chain>
<MsiPackage SourceFile="Setup.msi" Compressed="yes" />
</Chain>
</Bundle>
</Wix>
The Key attribute of <ApprovedExeForElevation> makes sense; it's a registry path to the entry that was created in my msi. The Value attribute is the ValueName in the registry that I created, containing the path to the .exe that I delivered in my install:
<Component Id="Comp_Client_Service.exe" Guid="PUT-GUID-HERE">
<File Id="my.exe" Name="my.exe" Source="my.exe" KeyPath="yes" />
<RegistryValue
Root="HKLM"
Key="SOFTWARE\Company\Product"
Name="PathToExeDeliveredByMSI"
Value="[INSTALLFOLDER]my.exe"
Type="string"/>
</Component>
Yet, this does not appear to be working. My .exe never launches, and the .log file provides no information that it is even attempting to launch it.
What is this code missing?
EDIT
The only piece of information that the log provides is that it is setting variables:
Initializing string variable 'LaunchTargetElevatedId' to value 'LaunchElevatedInstallProc'
Initializing string variable 'LaunchArguments' to value '/s'
According to the documentation, the TargetPath attribute on the WixStandardBootstrapperApplication must also be set. WixStdBA falls back to launching the exe at this path unelevated if anything went wrong trying to launch it elevated.
Id of the target ApprovedExeForElevation element.
If set with LaunchTarget, WixStdBA will launch the application
through the Engine's LaunchApprovedExe method instead of through ShellExecute.
You also need a button on the Success page with the name LaunchButton in your theme.

Wix util:registrysearch unrecognized

I am using Sharp Develop 4.4.1 to create a wix installer package for my application. The WIX version is the one that came with Sharp Develop, namely version 3.8.
My MSI project builds just fine.
Now I want to include the MSI in a bundle. In the bundle, I want to check if .net 4.5 and ghostscript are installed (otherwise install it). The .net package check is a breeze using packagegroupref.
So far so good.
However, I also want to check if Ghostscript is installed and intend to do this by doing a registry search. Since I am working in a Bundle, I am trying to use <util:RegistrySearch....., but I get an error stating: 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. (CNDL0200) - d:\SharpDev Projects\NREOutlookTest1\AIFBundle\Setup.wxs:20
This is my bundle code:
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Bundle UpgradeCode="ae0120aa-0ba8-45ac-b3e5-fce0f6b05de6"
Name="!(bind.packageName.AIF)"
Version="!(bind.packageVersion.AIF)"
Manufacturer="!(bind.packageManufacturer.AIF)"
IconSourceFile=".\images\stamp.ico">
<WixVariable Id="WixStdbaLicenseUrl" Value="myurl" />
<WixVariable Id="WixStdbaLogoFile" Value="..\NREOutlookTest1\images\stamp.jpg" />
<WixVariable Id="WixStdbaLogoSideFile" Value="..\NREOutlookTest1\images\stamp.jpg" />
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.HyperlinkSidebarLicense" />
<Chain>
<PackageGroupRef Id="NetFx45Web" />
<PackageGroupRef Id="Ghostscript" />
<MsiPackage Id="AIF" SourceFile="..\AIFSetup\bin\Release\AIFSetup.msi" Visible="no" />
</Chain>
</Bundle>
<Fragment>
<util:RegistrySearch Root="HKLM" Key="SOFTWARE\GPL Ghostscript\9.14" Value="GS_DLL" Variable="GhostScriptDetect" />
<PackageGroup Id="Ghostscript">
<ExePackage
Id="gs914"
DisplayName="GPL Ghostscript"
Cache="no"
Compressed="no"
Permanent="no"
Vital="yes"
DetectCondition="GhostScriptDetect >> "gsdll32.dll""
InstallCommand="/S"
SourceFile="gs914w32.exe"
DownloadUrl="http://downloads.ghostscript.com/public/gs914w32.exe" />
</PackageGroup>
</Fragment>
</Wix>
I have included the Wix Extension WixUtilExtension.dll in the project:
OK. I am officially an idiot. I have a post compile script running in sharpdevelop that is doing a candle and light action. I forgot to include the extension in the candle command, which gave me the error. DOH!!

Launch InstallShield 7 EXE from WIX Burn bootstrapper

I have the following WIX Burn bootstrapper 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">
<Bundle Name="Test" Version="1.0.0.0" Manufacturer="Test" UpgradeCode="cc44096e-23a6-48ab-a1f1-c75648358049">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.HyperlinkLicense">
<bal:WixStandardBootstrapperApplication SuppressOptionsUI="yes" LicenseUrl="" LogoFile="Logo.bmp"/>
</BootstrapperApplicationRef>
<Variable Name="InstallParameter" bal:Overridable="yes" Type="string" Value="" />
<Chain>
<ExePackage Name="VS2012_Redist_x86_exe" SourceFile="..\vcredist_x86_2012.exe" DetectCondition="ExeDetectedVariable" Permanent="yes" InstallCommand='/Q' />
<ExePackage Name="Pack" SourceFile="..\Install.exe" DetectCondition="ExeDetectedVariable" Permanent="no" InstallCommand='[InstallParameter]' />
</Chain>
</Bundle>
</Wix>
So, it first launches the Visual Studio 2012 redistributable and then the Install.exe.
Install.exe is a setup build with InstallShield 7 (not an MSI based one).
The WIX code compiles fine using WIX 3.7. When running the installer, the VS redistributable installs fine, but the Install.exe starts and when trying to copy the first file it gives me:
---------------------------
Component transfer error
---------------------------
Component: Component1.
File Group:
File:
Error: Catastrophic failure
Any idea how I can launch this InstallShield based installer from the WIX Burn bootstrapper?
EDIT: Turns out the problem was with the Name="Pack" attribute in the second ExePackage. Simply removing that attribute made the installer work. I find it very strange that that attribute can have such side-effect.
Turns out the problem was with the Name="Pack" attribute in the second ExePackage. Simply removing that attribute made the installer work. I find it very strange that that attribute can have such side-effect.