Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Javascript

Incrementing AssemblyVersion revision number on each build

4.88/5 (21 votes)
2 Oct 2011CPOL2 min read 76.1K  
Change the revision number of your project without manual intervention.

On each release (or build operation), we are incrementing our build number to flag that we've done something different. Although Visual Studio has an auto-build/revision feature (use the "*" in the AssemblyVersion attribute), like the following code shows:

C#
[assembly: AssemblyVersion("1.0.0.*")]

However, that number begins from a very large value. Some of us would love to start from 1 and increment the revision number one by one. Hereby, I wrote this script to do the job.

JavaScript
var al = WScript.Arguments.length;
if (al < 1) {
    WScript.StdErr.WriteLine ("Error: Missing input file name.");
    WScript.Quit(-1);
}
var n = WScript.Arguments(0); // file name
var c = al > 1 ? WScript.Arguments(1) : ""; // config name

var sh = new ActiveXObject("Shell.Application");
var f = sh.NameSpace(n.replace(/\\[^\\]+$/g, "")).ParseName(n.replace(/.+?\\([^\\]+)$/g, "$1"));
var ft = f.ModifyDate; // Keep the original modification date/time of the file

var s = new ActiveXObject("ADODB.Stream");
    s.Open();
    s.Type = 2;
    s.CharSet = "UTF-8"; // Make SURE that the encoding is correct, otherwise damage may occur
    s.LoadFromFile (n);
var t = s.ReadText ();
var r = /\[assembly:\s*(System\.Reflection\.)?AssemblyVersion(
               ?:Attribute)?\s*\(\s*"(\d+\.\d+\.)(\d+)\.(\d+)"\s*\)\s*\]/g;
var a = r.exec(t);
if (a != null && a.length > 1) {
    var ns = a[1]; // System.Reflection.
    var m = a[2]; // Major.Minor.
    var b = parseInt(a[3]); // Build
    var rv = parseInt(a[4]); // Revision
    if (c != "Release") { // change the number according to the build configuration
        rv++;
    }
    else {
        b++;
    }
    var v = "[assembly: "+ns+"AssemblyVersion (\""+m+b+"."+rv+"\")]";
    WScript.StdOut.WriteLine ("Assembly version changed: " + a[0] + "->" + v);
    t = t.replace(r, v);
}
else {
    WScript.StdErr.WriteLine ("Error: AssemblyVersion not found.");
    WScript.Quit(-1);
}

// further processing of the file is possible here

// save the result
s.Position = 0;
s.WriteText (t);
s.SetEOS ();
s.SaveToFile (n, 2);
s.Close ();

f.ModifyDate = ft; // Reset the modification date/time to prevent unnecessary rebuild afterwards

The above code simply reads a C# file, searches the "[assembly: AssemblyVersion" part of it and uses a regular expression to replace the revision number.

Having the above code, we can save it as a JavaScript file (I save the file into the solution directory and name it as "AutoIncrementBuildNumber.js") and add the following line onto the post-build procedure of the project. Therefore, the build/revision number will automatically be increased by one after each successful release or rebuild.

CScript.exe "$(SolutionDir)AutoIncrementBuildNumber.js" 
  "$(SolutionDir)Properties\AssemblyInfo.cs" "$(ConfigurationName)"

The build number will be incremented after each release. The revision number will be incremented on each debug build. If you don't provide the "$(ConfigurationName)" argument on the above line of post-build event, only revision number will be changed.

If you don't want to increment the build/revision number when you are debugging, you can use conditional statements to limit the increment to "Release" builds only, like the following command shows:

C#
if /I "$(ConfigurationName)" == "Release" CScript.exe "$(SolutionDir)AutoIncrementBuildNumber.js" 
   "$(SolutionDir)Properties\AssemblyInfo.cs"

Rewriting the AssemblyInfo.cs file will change its modification time and cause the compiler to rebuild the project each time you build the solution in Visual Studio, even if you don't change any code files in that project, since the AssemblyInfo.cs file is modified after a successful build and has a later modification time than the target assembly file. This can cause some problems. To avoid such kind of unnecessary rebuilds, the code first retrieves the modification time of the AssemblyInfo.cs file and then reset it after incrementing the build number. Therefore, the modification time is unchanged and Visual Studio won't rebuild the project unless you do make some modification to the source code files. The following is the code which does the job of avoiding rebuild:

JavaScript
var sh = new ActiveXObject("Shell.Application");
var f = sh.NameSpace(n.replace(/\\[^\\]+$/g, "")).ParseName(n.replace(/.+?\\([^\\]+)$/g, "$1"));
var ft = f.ModifyDate; // Keep the original modification date/time of the file
...
f.ModifyDate = ft; // Reset the modification date/time to prevent unnecessary rebuild

Hope this helps.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)