I want to include some dynamic part in the filename of the msi file my wix projects produce. This dynamic part should be controlled by variables which are part of my wix project and are declared like this:
<?define ProductVersion="7.1.0.1" ?>
Does anybody know about a way of sending that value of that wix variable to the linker to use it as a part of the output filename?
By the way: I'm using Wix3
Adding a WiX setup project In Visual Studio, open your solution, and add a WiX project to it: go to the Visual Studio main menu and click File -> Add -> New Project to open the Add New Project dialog. Choose the Setup Project item in the Windows Installer XML node, specify the project name and click OK.
Windows Installer XML Toolset (WiX, pronounced "wicks"), is a free software toolset that builds Windows Installer packages from XML. It consists of a command-line environment that developers may integrate into their build processes to build MSI and MSM packages.
WiX is a set of tools that allows you to create Windows Installer-based deployment packages for your application. The WiX toolset is based on a declarative XML authoring model. You can use WiX on the command line by using the WiX tools or MSBuild.
You could update the OutputName of your .wixproj and use an MSBuild variable to pass through the version number or any other variable you like.
My build script looks like this:
set PRODUCTVERSION=7.1.0.1
MSBuild.exe /p:Configuration=Debug /p:ProductVersion=%PRODUCTVERSION% Installer.wixproj
And my WiX project looks like this:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>1.0.0.0</ProductVersion>
<ProjectGuid>{b7415c44-8d59-4ac2-b698-03e399a305e3}</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName>Installer.$(ProductVersion)</OutputName>
...
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
<DefineConstants>Debug</DefineConstants>
<WixVariables>ProductVersion=$(ProductVersion)</WixVariables>
</PropertyGroup>
...
</Project>
The output would be:
Installer.7.1.0.1.msi
The msi file name is not determined by your wix files, but by the light.exe -out
switch. You can use the same value for -out
and inside your wix files if you do the following in your build script, assuming it is a batch script:
set
productversion=1.2.3
-out foo%productversion%.msi
to the
light.exe
linker$(env.productversion)
Open *.wixproj (example: Setup.wixproj
)
Go to the end of the file.
$(Configuration)
= Debug| Release …
Set path of your application on AssemblyFiles.
<Target Name="BeforeBuild">
<GetAssemblyIdentity AssemblyFiles="..\App\bin\$(Configuration)\App.exe">
<Output TaskParameter="Assemblies" ItemName="AsmInfo" />
</GetAssemblyIdentity>
<CreateProperty Value="$(SolutionName)_%(AsmInfo.Version)_$(Configuration)">
<Output TaskParameter="Value" PropertyName="TargetName" />
</CreateProperty>
</Target>
Output = App_1.0.0.0_Debug.msi
I found a couple of great reference posts to do just this operation:
http://blog.tentaclesoftware.com/archive/2009/05/03/38.aspx
and a follow-on with a better method of creating the output file using a pre-build event:
http://blog.tentaclesoftware.com/archive/2010/08/05/99.aspx
I know the links are old, but the method is sound.
Here are the basic steps:
Put the version you wish to use into a file you can access from your project. I use the main executable of my installation because I also bind to that version in my wxs. In my case, since I am building with C# and use SVN, I have a template version of my assembly.cs, assembly.cs.txt, that I run subwcrev on as a pre-build event to create the assembly.cs that gets compiled into my executable (I actually do it in a separate project in my solution). Subwcrev inserts some date and revision information that I use to create a version in the form "major.minor.version.0" where I use "year.month.revision.0" for my version.
Now, I usually just set AssemblyFileVersion with this method, but to be able to use my version number in the wixproj build event referenced in the post above, I also need to set AssemblyVersion since that is what can be accessed with GetAssemblyIdentity. This method would be questionable if I were really using an assembly someone else links to, but for me it is OK since it is in my final application executable.
Follow the steps outlined in the second post (the first post discusses using the binding method for version in wxs and how to unload and edit the wixproj - valuable context for the second post).
Works like a charm!
Update some years later - it looks like the links I referenced are dead. Here is a snapshot of what I changed to make it work.
In my main product wxs file, I changed (some names have been changed or omitted to protect the innocent and the guilty):
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
<Component Id="ProductComponent" Guid="DF1AB3A6-17D0-4176-B3AC-C073AC47AA80">
<RemoveFile Id="PurgeAppFolder" Name="*.*" On="uninstall" />
<File Source="$(var.MyApp.TargetPath)" KeyPath="yes"/>
<File Source="$(var.MyApp.ProjectDir)\bin\Release\MyData.dll"/>
<File Source="$(var.MyApp.ProjectDir)\bin\$(var.MyApp.Configuration)\ICSharpCode.SharpZipLib.dll"/>
</Component>
</ComponentGroup>
to
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
<Component Id="ProductComponent" Guid="DF1AB3A6-17D0-4176-B3AC-C073AC47AA80">
<RemoveFile Id="PurgeAppFolder" Name="*.*" On="uninstall" />
<File Id="MAINEXECUTABLE" Source="$(var.MyApp.TargetPath)" KeyPath="yes">
<Shortcut Directory="ApplicationProgramsFolder" Id="MYAPPEXEAPF" Name="My App Name" Icon="MyAppIcon.exe" IconIndex="0" Advertise="yes" />
<Shortcut Directory="ApplicationDesktopFolder" Id="MYAPPEXEADF" Name="My App Name" Icon="MyAppIcon.exe" IconIndex="0" Advertise="yes" />
</File>
<File Source="$(var.MyApp.ProjectDir)\bin\Release\MyData.dll"/>
<File Source="$(var.MyApp.ProjectDir)\bin\$(var.MyApp.Configuration)\ICSharpCode.SharpZipLib.dll"/>
</Component>
</ComponentGroup>
and up at the top I added:
<Product Id="C86505BF-303F-4D6B-8F5F-43A57635F85D" Name="My Application Name" Language="1033" Version="!(bind.FileVersion.MAINEXECUTABLE)" Manufacturer="My Software Shop" UpgradeCode="D1C628E5-5478-4DA5-A31A-F9191D5B1544">
Note that the Version is bound to the file version of MAINEXECUTABLE, which is defined in the main product component.
I hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With