I have found several ways of injecting a version number into Wix via TeamBuild, but most of them require way too much work. After a few days of experimenting I ended up with this solution.
My TFSBuild.proj file contains the Major and Minor versions and a target "GenerateBuildNumber" to generate build and revision numbers. I use these to create a 'Versionnumber' property and add that to the <custompropertiesforbuild> property.
<propertygroup>
<assemblymajorversion>2</assemblymajorversion>
<assemblyminorversion>7</assemblyminorversion>
<custompropertiesforbuild>
SignAssembly=true;DelaySign=false;AssemblyOriginatorKeyFile=$(PrivateKeyLocation)
</custompropertiesforbuild>
</propertygroup>
<target name="BuildNumberOverrideTarget" dependsontargets="GenerateBuildNumber">
<createproperty value="$(AssemblyMajorVersion).$(AssemblyMinorVersion).$(GeneratedBuildNumber).$(GeneratedRevisionNumber)">
<output taskparameter="Value" propertyname="Versionnumber" />
</createproperty>
<!-- Add the dynamically generated Versionnumber to the custom build properties for use in the WIX project -->
<createproperty value="$(CustomPropertiesForBuild);Versionnumber=$(Versionnumber)">
<output taskparameter="Value" propertyname="CustomPropertiesForBuild" />
</createproperty>
</target>
For setting the version number in a WiX project, you need to get the value in the Product.wxs file. My predecessor had defined PRODUCTVERSION to contain a placeholder value "_versionnumber_".
Note: The official way would have been to use the <defineconstants> in the WiX project file but in my case, other builds were already depending on the placeholder so I didn't want to change this.
<?define PRODUCTVERSION="_versionnumber_"?>
In my WiX project file I have overriden the "BeforeBuild" target to replace the "_versionnumber_" placeholder with the actual value of $(Versionnumber). I'm using the 'File.Replace' task from the SDC Tasks library.
<Target name="BeforeBuild">
<microsoft.sdc.tasks.file.replace
Path="Product.wxs"
OldValue="%22_versionnumber_%22"
NewValue="%22$(Versionnumber)%22"
Force="true"
IgnoreCase="true">
</Target>
As a final step, I have overriden the "AfterBuild" target of the WiX project to rename the output msi in order to contain the versionnumber in the filename as well.
<Target name="AfterBuild">
<Createproperty value="$(TargetDir)%(CultureGroup.OutputFolder)">
<Output taskparameter="Value" propertyname="TargetDir">
</CreateProperty>
<Copy sourcefiles="$(TargetDir)$(TargetName)$(TargetExt)"
destinationfiles="$(TargetDir)$(TargetName).$(Versionnumber)$(TargetExt)">
<Delete files="$(TargetDir)$(TargetName)$(TargetExt)">
</Target>