Specify the INSTALLLOCATION of packages in WiX inside the Burn managed bootstrapper - wix

I have a WiX 3.6 bundle (using Burn) and managed bootstrapper that install several MSI packages. Some of the packages install to a common location (C:\program files\MyApp).
I want to let the user choose the install location inside the managed bootstrapper application (C# WPF, especially because the application is large to install; about 1 GB). How can I specify the INSTALLLOCATION for each MSI packages inside my bundle?

Use an MsiProperty child for each MsiPackage to specify INSTALLLOCATION=[BurnVariable]. Then use Engine.StringVariables to set BurnVariable.
For example, in your bundle you set:
<Bundle ...>
<Variable Name='BurnVariable' Value='bar' />
...
<Chain>
<MsiPackage Source='path\to\your.msi'>
<MsiProperty Name="INSTALLLOCATION" Value="[BurnVariable]" />
</MsiPackage>
</Chain>
</Bundle>
See also the FireGiant explanation on this topic.
Then in the managed bootstrapper you can do something similar to this:
Engine.StringVariables["BurnVariable"] = "C:\program files\MyApp";

Related

Set MsiPackage's as features

I am creating a Wix Installer with wix bootstrapper. Wix setup project gives you the possibility to determine which features to install and which not. I am looking the same thing for MsiPackages on bootstrapper, so I can select which msi packages to install.
<Chain>
<!-- TODO: Define the list of chained packages. -->
<!-- <MsiPackage SourceFile="path\to\your.msi" /> -->
<MsiPackage SourceFile="..\APP1\Wix1WindowsFormsApplication1.msi"/>
<MsiPackage SourceFile="..\APP2\Wix2WindowsFormApplication2.msi"/>
</Chain>
This can be done in a custom bootstrapper application in which you have PlanPackageBegin event where you can select which msi packages to install. But this is not easy.
With standard bootstrapper application there is a very limited capability to define checkboxes on the Options dialog and use selection of checkboxes to select which packages to install, as discussed here: http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/Bootstrapper-Custom-UI-Checkbox-to-customize-install-td7596905.html

WIX Bootstrapper uninstall without uninstalling MSI how to?

I'm building a WIX Bundle/Chain bootstrapper. It runs and installs like I specified.
I would like to be able to uninstall the bootstrapper without installing the installed MSI. How to accomplish that?
I'm using WIX 3.11.
Other posting here seem to have the opposite behaviour and demand. They seem to use other versions of wix (<=3.10).
Is there a way to accomplish that behaviour?
Some snippets:
...
</Chain>
TK
In your MsiPackage node, add the Permanent flag and set it to yes. When you uninstall your bootstrapper, the msi(s) set this way will remain installed on the machine.
<MsiPackage Id="MSI2KEEP"
Cache="no"
Compressed="yes"
Name="MSI2KEEP"
ForcePerMachine="yes"
DisplayInternalUI="no"
Vital="yes"
**Permanent="yes"**
SourceFile="$(var.MSI2KEEP.TargetPath)"
DisplayName="MSI 2 KEEP"
Description="MSI 2 KEEP" />

Generating an EXE from MSI in Wix

I'm tring to generate EXE file from MSI in Wix installer, I added a new project (Bootstrapper) but I can specifying the path of my MSI file
<Bundle Name="Bootstrapper" Version="1.0.0.0" Manufacturer="" UpgradeCode="e45fdbb6-192c-46f7-b4db-d04af69edada">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
<Chain>
<!-- TODO: Define the list of chained packages. -->
<MsiPackage SourceFile="WixSetup.msi" />
</Chain>
</Bundle>
Can you help ?
Thanks in advance
Abdulsalam
Add a reference of your msi's wixproj to your bootstrapper application.
You can now reference the msi file like this
<MsiPackage SourceFile="$(var.WixProjName.TargetPath)" />
This will automatically point to the debug location or release location depending on your build mode.
You can see a list of well-defined vars passed to candle.exe in the output when building. You'll see a bunch of defines like "-dWixProjName.Property=Value" and then you can use those values in your bundle xml like so $(var.WixProjName.Property) which will get replaced by the Value before compiling.
You can see a list of the defined properties when you reference another project here: http://wixtoolset.org/documentation/manual/v3/votive/votive_project_references.html

Create a Single MSI installer

I have developed a application which is in a 32-bit and 64-bit format. These applications require corresponding registry entries as well. I am delivering these as separate packages for 32-bit and 64-bit using WiX.
Now my requirement is to create a single installer which installs the components based on OS configuration. I tried using Bootstrapper to bundle my packages.
My bootstrapper code looks as below:
<Bundle Name="Bootstrapper" Version="1.0.0.0" Manufacturer="MYCOMPANY" UpgradeCode="b24f74ca-883c-4572-9479-37d92d733aa0">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
<Chain>
<ExePackage Id="source1" Compressed="yes" PerMachine="yes" SourceFile="32\Sample.exe" InstallCondition="Not VersionNT64" />
<ExePackage Id="source2" Compressed="yes" PerMachine="yes" SourceFile="64\Sample.exe" InstallCondition="VersionNT64" />
</Chain>
</Bundle>
My bootstrapper output is MSI. When I run the MSI I am getting MainEngineThread is returning 1620 in the verbose log.
Please suggest how can I bundle two EXE's to get single MSI package.
Error 1620 isn't particularly nasty - it just means it can't open the MSI file, and the simplest explanation for that is that your directory structure is incorrect and the exe is calling the MSI install with the incorrect location or name for the MSI file.

Wix burn upgrade needs to uninstall both MSI's before upgrading

I have two MSI's; framework.msi and product.msi. The framework.msi installs dll's into the GAC that the product.msi depends on for both install and uninstall.
I've created a BA that chains the two MSI's together.
<Bundle ...>
<Chain>
<PackageGroupRef Id='framework'/>
<PackageGroupRef Id='product'/>
</Chain>
</Bundle>
<Fragment>
<PackageGroup Id="framework">
<MsiPackage Name="Product Framework"
ForcePerMachine="yes"
SourceFile="framework.msi"
Vital="yes"
Cache="no"
Permanent="no"
Compressed="yes"
Visible="yes"/>
</PackageGroup>
<PackageGroup Id="product">
<MsiPackage Name="Product"
ForcePerMachine="yes"
SourceFile="product.msi"
Vital="yes"
Cache="no"
Permanent="no"
Compressed="yes"
Visible="yes"/>
</PackageGroup>
</Fragment>
For fresh installs, my framework.msi and product.msi install correctly. When I go to upgrade to a new version, it upgrades the framework.msi successfully. Then it proceeds to uninstall the product.msi but it fails (for this error: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.IO.FileNotFoundException: Could not load file or assembly 'CheckInstaller, Version=1.0.0.0' or one of its dependencies. The system cannot find the file specified.) because the uninstall CustomAction references a version of an assembly (CheckInstaller) that is no longer in the GAC (because it has been upgraded as part of the framework.msi upgrade).
Without having to write a custom BA, I want to be able to do something like this:
// pseudo code
if(product.Exists() && framework.Exists())
{
product.Uninstall(); // product is dependent on the framework
framework.Uninstall();
}
framework.Install();
product.Install();
I realize this would be possible if we were to combine the two MSI's into one big product but since we disperse the framework.msi to other teams and for various other reasons, they need to be kept separate.
Is what I want to do even possible to do with the WiX bootstrapper?
That isn't possible with Burn today. The chain is fixed. On install it runs through forward, on uninstall it runs through backwards. I can think of two options available today:
Do not have the MSI's upgrade each other and let the old MSIs be removed when the new Bundle uninstalls the old Bundle.
Avoid creating install time dependencies between packages. This generally is a good thing to do anyway.
A feature request might be to have the new Bundle have the ability to remove the old Bundle before installing instead of after like it is today, but that isn't supported at this point in time.