Introduction
Sometimes it could be useful to automatically increment the file version of an assembly at each build; this can be
done even if you don't know MSBuild, using T4.
Background
A T4 text template is a mixture of text blocks and control logic that can generate a text file. The control logic is written as fragments of program code in Visual C# or Visual Basic.
The generated file can be text of any kind, such as a Web page, or a resource file, or program source code in any language.
The T4 text templates can be translated by Visual Studio or by the TextTransform
utility, TextTransform.exe.
TextTransform.exe is a command-line tool that you can use to transform a text template. When you call
TextTransform.exe, you specify the name of a text template file as an argument.
TextTransform.exe calls the text transformation engine and processes the text template.
So, using a simple T4 template, and running the transformation on the pre-build event, it is possible to autoincrement easily the Assembly File Version of one (or more) assemblies.
This can be achieved by incrementing, for example, the revision number (the fourth from left, the 'X' in 1.0.0.X) each time the project is built.
Using the code
In order to achieve the automatic increment of the revision number:
- Right click on you csproj file, click on "Properties" on the context menu, click on the "Build Events" tab, then, add the following pre build action to the project:
First line:
set textTemplatingPath="%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\$(VisualStudioVersion)\texttransform.exe"
Second line:
if %textTemplatingPath%=="\Microsoft Shared\TextTemplating\$(VisualStudioVersion)\texttransform.exe" set textTemplatingPath="%CommonProgramFiles%\Microsoft Shared\TextTemplating\$(VisualStudioVersion)\texttransform.exe"
Third line:
%textTemplatingPath% "$(ProjectDir)AssemblyFileVersion.tt"
The first two lines of code sets a custom environment variable, "%textTemplatingPath%",
with the value of the "Common Files" folder that we need.
It is different on 32 bit machines and 64 bit machines. Using the MSBuild variable "$(VisualStudioVersion)" we make sure that the prebuild action we're writing will work on any VS version. The last line of code uses one environment variable, "%textTemplatingPath%", and another MSBuild variable, "$(ProjectDir)". Writing the path like this ensures that our solution is going to work with any version of Visual Studio
on a 32 or a 64 bit machine.
The first two lines of code sets a custom environment variable, "%textTemplatingPath%", with the value of the "Common Files" folder that we need.
It is different on 32 bit machines and 64 bit machines. Using the MSBuild variable "$(VisualStudioVersion)" we make sure that the prebuild action we're writing will work on any VS version. The last line of code uses one environment variable, "%textTemplatingPath%", and another MSBuild variable, "$(ProjectDir)". Writing the path like this ensures that our solution is going to work with any version of Visual Studio
on a 32 or a 64 bit machine.
- Remove the following line from the file AssemblyInfo.cs (usually located in the "Property" folder inside your C# project):
[assembly: AssemblyFileVersion("1.0.0.0")]
(Scroll down to the bottom in order to find it.)
- Add a new Text Template file "AssemblyFileVersion.tt" to the root folder of the project, copy inside of it the following t4 code, then you're done.
<#@ template language="C#" hostSpecific="True"#>
<#@ output extension="cs" #>
<#@ import namespace="System.IO" #>
<#
int revisionNumber;
try
{
using(var f = File.OpenText(Host.ResolvePath("AssemblyFileVersion.cs")))
{
string s = f.ReadLine().Replace("//","");
revisionNumber = int.Parse(s) + 1;
}
}catch
{
revisionNumber = 0;
}
#>
using System.Reflection;
[assembly: AssemblyFileVersion("1.0.0.<#= revisionNumber #>")]
- Now build the project. The generated "AssemblyFileVersion.cs" will be like the following:
using System.Reflection;
[assembly: AssemblyFileVersion("1.0.0.0")]
Points of Interest
There are many other ways to achieve this result (Build server, MSBuild, ...), but I particularly like this one because this could be an easy way to get started with T4,
even if you never used it. Of course the proposed solution can be easily improved.
The good point of this solution is that the automatic increment mechanism can be easily spotted, understood and modified, by any developer of your team.