How to have an auto incrementing version number (Visual Studio)?
This question already has an answer here:
If you add an AssemblyInfo class to your project and amend the AssemblyVersion attribute to end with an asterisk, for example:
[assembly: AssemblyVersion("2.10.*")]
Visual studio will increment the final number for you according to these rules (thanks galets, I had that completely wrong!)
To reference this version in code, so you can display it to the user, you use reflection. For example,
Version version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
DateTime buildDate = new DateTime(2000, 1, 1)
.AddDays(version.Build).AddSeconds(version.Revision * 2);
string displayableVersion = $"{version} ({buildDate})";
Two important gotchas that you should know
From @ashes999:
It's also worth noting that if both AssemblyVersion
and AssemblyFileVersion
are specified, you won't see this on your .exe.
From @BrainSlugs83:
Setting only the 4th number to be *
can be bad, as the version won't always increment. The 3rd number is the number of days since the year 2000, and the 4th number is the number of seconds since midnight (divided by 2) [IT IS NOT RANDOM]. So if you built the solution late in a day one day, and early in a day the next day, the later build would have an earlier version number. I recommend always using XY*
instead of XYZ*
because your version number will ALWAYS increase this way.
You could use the T4 templating mechanism in Visual Studio to generate the required source code from a simple text file :
I wanted to configure version information generation for some .NET projects. It's been a long time since I investigated available options, so I searched around hoping to find some simple way of doing this. What I've found didn't look very encouraging: people write Visual Studio add-ins and custom MsBuild tasks just to obtain one integer number (okay, maybe two). This felt overkill for a small personal project.
The inspiration came from one of the StackOverflow discussions where somebody suggested that T4 templates could do the job. And of course they can. The solution requires a minimal effort and no Visual Studio or build process customization. Here what should be done:
<#@ template language="C#" #>
//
// 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: AssemblyVersion("1.0.1.<#= this.RevisionNumber #>")]
[assembly: AssemblyFileVersion("1.0.1.<#= this.RevisionNumber #>")]
<#+
int RevisionNumber = (int)(DateTime.UtcNow - new DateTime(2010,1,1)).TotalDays;
#>
You will have to decide about version number generation algorithm. For me it was sufficient to auto-generate a revision number that is set to the number of days since January 1st, 2010. As you can see, the version generation rule is written in plain C#, so you can easily adjust it to your needs.
//
// 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: AssemblyVersion("1.0.1.113")]
[assembly: AssemblyFileVersion("1.0.1.113")]
Yes, today it's 113 days since January 1st, 2010. Tomorrow the revision number will change.
What I like about this approach is that it is lightweight (no custom MsBuild tasks), and auto-generated version information is not added to source control. And of course using C# for version generation algorithm opens for algorithms of any complexity.
This is my implementation of the T4 suggestion... This will increment the build number every time you build the project regardless of the selected configuration (ie Debug|Release), and it will increment the revision number every time you do a Release build. You can continue to update the major and minor version numbers through Application ➤ Assembly Information...
To explain in more detail, this will read the existing AssemblyInfo.cs
file, and use regex to find the AssemblyVersion
information and then increment the revision and build numbers based on input from TextTransform.exe
.
AssemblyInfo.cs
file. Create a AssemblyInfo.tt
file in its place. Visual Studio should create AssemblyInfo.cs
and group it with the T4 file after you save the T4 file.
<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<#
string output = File.ReadAllText(this.Host.ResolvePath("AssemblyInfo.cs"));
Regex pattern = new Regex("AssemblyVersion("(?<major>d+).(?<minor>d+).(?<revision>d+).(?<build>d+)")");
MatchCollection matches = pattern.Matches(output);
if( matches.Count == 1 )
{
major = Convert.ToInt32(matches[0].Groups["major"].Value);
minor = Convert.ToInt32(matches[0].Groups["minor"].Value);
build = Convert.ToInt32(matches[0].Groups["build"].Value) + 1;
revision = Convert.ToInt32(matches[0].Groups["revision"].Value);
if( this.Host.ResolveParameterValue("-","-","BuildConfiguration") == "Release" )
revision++;
}
#>
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Resources;
// General Information
[assembly: AssemblyTitle("Insert title here")]
[assembly: AssemblyDescription("Insert description here")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Insert company here")]
[assembly: AssemblyProduct("Insert product here")]
[assembly: AssemblyCopyright("Insert copyright here")]
[assembly: AssemblyTrademark("Insert trademark here")]
[assembly: AssemblyCulture("")]
// Version informationr(
[assembly: AssemblyVersion("<#= this.major #>.<#= this.minor #>.<#= this.revision #>.<#= this.build #>")]
[assembly: AssemblyFileVersion("<#= this.major #>.<#= this.minor #>.<#= this.revision #>.<#= this.build #>")]
[assembly: NeutralResourcesLanguageAttribute( "en-US" )]
<#+
int major = 1;
int minor = 0;
int revision = 0;
int build = 0;
#>
Add this to your pre-build event:
"%CommonProgramFiles(x86)%microsoft sharedTextTemplating$(VisualStudioVersion)TextTransform.exe" -a !!BuildConfiguration!$(Configuration) "$(ProjectDir)PropertiesAssemblyInfo.tt"
上一篇: 维护程序集版本号的最佳实践/指导