Wix - automate 32bit and 64bit build - msbuild

Going from this answer https://stackoverflow.com/a/15985524/552448
<Wix>
<Bundle...>
<BootstrapperApplicationRef Id='WixStandardBootstrapperApplication.HyperlinkLicense' />
<Chain>
<MsiPackage SourceFile="prereq1.msi" />
....
<MsiPackage InstallCondition='NOT VersionNT64' SourceFile='path\to\x86.msi' />
<MsiPackage InstallCondition='VersionNT64' SourceFile='path\to\x64.msi' />
</Chain>
</Bundle>
</Wix>
All the projects in my solution target "Any CPU", with the exception of the bootstrapper and the MSI package, thus I'm using a shared cabinet to avoid doubling the final size of the bootstrapper.
I know I have to build the MSI with x86, then with x64 and finally build the bootstrapper. Did this manually and it works.
However, I'd like to automate these steps.
I've been trying to add a Prebuild event to the Bundle wixproj file, something along the lines of
$(MSBuildBinPath)\msbuild "$(SolutionDir)MyMSI\MyMSI.wixproj" /p:Platform=x86;Configuration=Release
$(MSBuildBinPath)\msbuild "$(SolutionDir)MyMSI\MyMSI.wixproj" /p:Platform=x64;Configuration=Release
However, this fails with this error:
The OutputPath property is not set for project 'MyLibrary.csproj'. Please check to make sure that you have specified a valid combination of Configuration and Platform for this project. Configuration='Release' Platform='x86'. You may be seeing this message because you are trying to build a project without a solution file, and have specified a non-default Configuration or Platform that doesn't exist for this project.
I'd like to make it work without having to go through all the projects in order to add the combination of platform/configuration. After all, this works if I right click MyMSI and choose build.
Surely I must be missing something.

It was pretty obvious - create two separate MSI projects - one with x86, the other with x64, both using the same files.

Related

Wix granular bundling

I'd like to achieve more granularity when producing final installer for my program.
For the sake of example, lets assume this is called: The Program. It consists of Client and Server.
In this example, we have 5 projects.
Client.csproj
Server.csproj
ClientInstaller.wixproj
ServerInstaller.wixproj
Bundle.wixproj
Everything's perfect if I just build the installer with through Bundle project. But how I'd like it to happen is to first build the Client and Server (separately) to run the tests and in case of success - produce artifacts, which then will be used by Budle to produce final installer.
Currently I'm doing this successfully with just Client, msbuild Client.csproj /p:OutputPath=$binariesPath produces the output in specified location, then
msbuild Bundle.wixproj /p:OutputPath=$installerPath /p:LinkerBindInputPaths=$binariesPath consumes this output and produces installer at $installerPath
I tried multiple LinkerBindInputPaths like /p:LinkerBindInputPaths=$binariesPath\Client /p:LinkerBindInputPaths=$binariesPath\Server, but this did not seem to work.
Perhaps I could squeeze one more step and build each installer. That allows me to get separate MSI for each component.
Currently each MSI is strictly related to its installer project:
<MsiPackage Id="Client" SourceFile="$(var.ClientInstaller.TargetPath)" Vital="no" /> <MsiPackage Id="Server" SourceFile="$(var.ServerInstaller.TargetPath)" Vital="no" />
So my question is: How to build Bundle.wixproj so that I can override MSI source file location with custom one, where the output of my previous builds is located?

In a WiX Bundle, how can I supply a settings file for an ExePackage?

I am authoring a WiX bundle that installs several other pre-build packages, some are MSIs and some are EXEs.
One of the EXE packages requires a settings file to be supplied which I have to give the path to on the command line.
<ExePackage Id="exePackage"
Description="Executable Installer"
PerMachine="yes"
InstallCommand="-settings=TheConfigurationFile.txt"
SourceFile="RedistributablePackages\TheInstaller.exe" >
How should I package TheConfigurationFile.txt so that the EXE installer can find it? It isn't clear to me how to do that as I can't seem to find any way to specify a file in connection with the ExePackage...?
Check out the Payload element.
<Payload SourceFile="TheConfigurationFile.txt"/>

Getting Package InstallCondition In Wix Managed Bootstrapper Application

I have a Wix Bundle that contains several packages. A couple of packages are mutually exclusive. By that I mean they are both included because one needs to be installed on 32-bit machines, the other on 64-bit machines. To solve that problem, I have defined a package group like this:
<Fragment>
<PackageGroup Id="Drivers">
<MsiPackage Id="Driversx64" InstallCondition="VersionNT64" SourceFile="SRC\drivers64.msi" DisplayInternalUI="no" Visible="no" ForcePerMachine="yes" EnableFeatureSelection="yes"/>
<MsiPackage Id="Driversx86" InstallCondition="NOT VersionNT64" SourceFile=".SRC\drivers32.msi" DisplayInternalUI="no" Visible="no" ForcePerMachine="yes" EnableFeatureSelection="yes"/>
</PackageGroup>
</Fragment>
And then, in the chain I just include the <PackageGroupRef Id="Drivers"/>
Things work as expected in that the engine correctly plans the installation based on the operating system.
The trouble I'm having is I want to display a list of packages that will be installed and I would like to:
determine from the custom bootstrapper whether a package is supposed to be visible to the UI or not, and maybe it's level
determine from the custom bootstrapper whether a package's InstallCondition evaluates to true of false
The bottom line though is I want to make sure my custom BA can obey what's declared in the bundle as far as what packages are allowed to be installed on the target system.
During runtime, there will be a file called BootstrapperApplicationData.xml. This file will contain information about each package, including InstallCondition (not sure when it was added, may require v3.10.3). You'll be able to pass the value of each condition to the Engine's EvaluateCondition method to determine whether it is true or false.

How to build a bootstrapper for multiple MSI files?

I've got following problem: With WiX 3.7 I have built an installer which creates several localized MSI files, for example:
..\bin\x86\Release\en-us\myProject.msi
..\bin\x86\Release\fr-fr\myProject.msi
..\bin\x86\Release\de-de\myProject.msi
Furthermore, I created a Burn bootstrapper project which should ensure that .NET 4.5 is installed:
...
<Chain>
<PackageGroupRef Id="NetFx45Web"/>
<MsiPackage SourceFile="$(var.myProject.TargetPath)"></MsiPackage>
</Chain>
...
Now I have expected that the Burn bootstrapper project creates:
..\bin\x86\Release\en-us\myProject.exe
..\bin\x86\Release\fr-fr\myProject.exe
..\bin\x86\Release\de-de\myProject.exe
but MsiPackage expects a single file.
Is it generally possible to make the Burn project work as I expect?
If this is not the case, is it possible to get to know how the exact name of the created MSI file? I can not hard code the MSI file name, because the output name can vary.
I don't think that this is possible... If you are using MSBuild or something similar you can build it as you're building your MSI packages.
Or you can use a simple script which will call candle.exe with parameter -dYOUR_VARIABLE=myProject.msi.
See Working with MSBuild for more information.

Copy file using Burn

I am using WiX Burn to make my installer, i am bundling one exe and one msi.
And the exe needs an properties file at the time of install.
Is there a way to copy the file using burn, i tried Payload but it is not working.
Can i know the location throguh any Bundle variable where my file is copied.
Thanks
Ravi S
Make sure you are specifying the properties file as the payload for the exe and not for the bootstrapper. For example, in your bundle, your chain may look something like this:
<Chain>
<MsiPackage SourceFile="MyInstaller.msi" Id="MyInstaller" Cache="yes"/>
<ExePackage SourceFile="MyExe.exe" Id="MyExe" Cache="yes">
<Payload SourceFile="OtherFile.properties" Id="Properties"/>
</ExePackage>
</Chain>
Also, as a sanity check, which version of WiX are you using? If you are using an older build (such as RC0), you could try updating to the latest weekly build.
Update:
In WiX 3.6 it does not appear that you can get the absolute path of a payload file. There are two bugs/feature request open right now regarding the issue that are deferred to WiX 3.7:
Add burn variable to cache path - ID: 3557446
Change working folder to the cache folder - ID: 3538846
One workaround would be to use burn to write your own bootstrapper application and then programmatically determine the working directory and set the appropriate parameters, but that would be a lot of work for this one issue.