Click here to Skip to main content
15,509,706 members
Articles / Programming Languages / C#
Tip/Trick
Posted 20 Sep 2013

Tagged as

Stats

83.6K views
744 downloads
38 bookmarked

Walkthrough: How to increment AssemblyFileVersion automatically at each build using T4

Rate me:
Please Sign up or sign in to vote.
4.96/5 (22 votes)
25 Sep 2013Ms-PL3 min read
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.

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:

  1. 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: 
  2. 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.

    Image 1

  3. Remove the following line from the file AssemblyInfo.cs (usually located in the "Property" folder inside your C# project):
  4. [assembly: AssemblyFileVersion("1.0.0.0")]

    (Scroll down to the bottom in order to find it.)

    Image 2

  5. 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.
  6. C#
    <#@ template language="C#" hostSpecific="True"#>
    <#@ output extension="cs" #>
    <#@ import namespace="System.IO" #>
    <#
        int revisionNumber;
        try
        {
            //If we cannot find the file, the revision number is set to zero,
            //so even if the file doesn't exists the generation will run anyway.
            //NOTE: we suppose we're not messing with the generated file
            using(var f = File.OpenText(Host.ResolvePath("AssemblyFileVersion.cs")))
            {
                //We're reading the previous revision number; in order to make the
                //code as simple as we can, we're just going to rewrite it on the first row, commented.
                //This is not elegant, but it's simple enough and quite effective.
                string s = f.ReadLine().Replace("//","");
                revisionNumber = int.Parse(s) + 1; 
            }
        }catch
        {     
            revisionNumber = 0; 
        }
    #>
    //<#=revisionNumber#>
    // 
    // This code was generated by a tool. Any changes made manually will be lost
    // the next time this code is regenerated.
    // 
    
    using System.Reflection;
    
    [assembly: AssemblyFileVersion("1.0.0.<#= revisionNumber #>")]

    Image 3

    Image 4

    Image 5

  7. Now build the project. The generated "AssemblyFileVersion.cs" will be like the following:
  8. C#
    //0
    // 
    // This code was generated by a tool. Please do not change this document in any of its parts.
    // 
    
    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.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


Written By
Software Developer
New Zealand New Zealand
Software Developer

Comments and Discussions

 
QuestionFor Visual Studio 2022 Pin
iamhammer25-May-22 8:06
iamhammer25-May-22 8:06 
QuestionHow do i update my assembly version for only release DLL which gets generated on build Pin
Member 138996097-Jul-18 2:11
Member 138996097-Jul-18 2:11 
QuestionNearly the same solution, but now read the version number from a file in the solution directory Pin
Harm Salomons12-Jan-17 7:06
Harm Salomons12-Jan-17 7:06 
QuestionNice article! Pin
Manuel Paz2-Sep-15 7:48
Manuel Paz2-Sep-15 7:48 
QuestionHow to Read the AssemblyFileVersion Pin
Nigel Brown29-Apr-15 1:19
Nigel Brown29-Apr-15 1:19 
QuestionMy vote of 5 Pin
SB525-Sep-13 9:54
SB525-Sep-13 9:54 
GeneralMy vote of 5 Pin
fredatcodeproject25-Sep-13 6:23
professionalfredatcodeproject25-Sep-13 6:23 
GeneralMy vote of 5 Pin
johannesnestler25-Sep-13 4:34
johannesnestler25-Sep-13 4:34 
GeneralNotes Of Reading Pin
Champion Chen24-Sep-13 21:01
Champion Chen24-Sep-13 21:01 
GeneralRe: Notes Of Reading Pin
Bruno Tagliapietra24-Sep-13 23:22
Bruno Tagliapietra24-Sep-13 23:22 
GeneralRe: Notes Of Reading Pin
Champion Chen25-Sep-13 21:34
Champion Chen25-Sep-13 21:34 
QuestionRe: Notes Of Reading Pin
Bruno Tagliapietra25-Sep-13 23:01
Bruno Tagliapietra25-Sep-13 23:01 
AnswerRe: Notes Of Reading Pin
Champion Chen25-Sep-13 23:23
Champion Chen25-Sep-13 23:23 
Before building , template will read versions info from proerties\assemblyversion.cs , when assemblyversion.cs's content(without assemblyversionattribute and assemblyfileversionattribute) be cached .
if GetAssemblyInfo method find the two attributes existed in assemblyversion.cs , assemblyversion.cs will be replaced by cached contents , then that two attributes disappears .
Because all above happened in pre-building , so building will not be affected .

i am just a little lazy and just not want to copy projects' attribute in assemblyfileversion.cs , so let template do it .
QuestionRe: Notes Of Reading Pin
Bruno Tagliapietra25-Sep-13 23:28
Bruno Tagliapietra25-Sep-13 23:28 
AnswerRe: Notes Of Reading Pin
Champion Chen26-Sep-13 0:03
Champion Chen26-Sep-13 0:03 
GeneralRe: Notes Of Reading Pin
Bruno Tagliapietra27-Sep-13 2:43
Bruno Tagliapietra27-Sep-13 2:43 
GeneralMy vote of 5 Pin
Champion Chen24-Sep-13 17:11
Champion Chen24-Sep-13 17:11 
QuestionRe: My vote of 5 Pin
Bruno Tagliapietra24-Sep-13 22:38
Bruno Tagliapietra24-Sep-13 22:38 
AnswerRe: My vote of 5 Pin
Champion Chen24-Sep-13 22:48
Champion Chen24-Sep-13 22:48 
AnswerRe: My vote of 5 Pin
Bruno Tagliapietra24-Sep-13 23:03
Bruno Tagliapietra24-Sep-13 23:03 
GeneralMy vote of 5 Pin
Valery Possoz23-Sep-13 10:18
professionalValery Possoz23-Sep-13 10:18 
GeneralNice tip... Pin
Kishor Deshpande23-Sep-13 1:09
professionalKishor Deshpande23-Sep-13 1:09 
GeneralNice article Pin
Luca Ritossa22-Sep-13 23:12
Luca Ritossa22-Sep-13 23:12 
SuggestionRe: Nice article Pin
Bruno Tagliapietra22-Sep-13 23:38
Bruno Tagliapietra22-Sep-13 23:38 
GeneralMy vote of 5 Pin
Paulo Zemek20-Sep-13 8:56
Paulo Zemek20-Sep-13 8:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.