Can I automatically increment the file build version when using Visual Studio?

230,668

Solution 1

In visual Studio 2008, the following works.

Find the AssemblyInfo.cs file and find these 2 lines:

[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

You could try changing this to:

[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("1.0.*")]

But this won't give you the desired result, you will end up with a Product Version of 1.0.* and a File Version of 1.0.0.0. Not what you want!

However, if you remove the second of these lines and just have:

[assembly: AssemblyVersion("1.0.*")]

Then the compiler will set the File Version to be equal to the Product Version and you will get your desired result of an automatically increment product and file version which are in sync. E.g. 1.0.3266.92689

Solution 2

open up the AssemblyInfo.cs file and change

// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

to

[assembly: AssemblyVersion("1.0.*")]
//[assembly: AssemblyFileVersion("1.0.0.0")]

you can do this in IDE by going to project -> properties -> assembly information

This however will only allow you to auto increment the Assembly version and will give you the

Assembly File Version: A wildcard ("*") is not allowed in this field

message box if you try place a * in the file version field.

So just open up the assemblyinfo.cs and do it manually.

Solution 3

Another option for changing version numbers in each build is to use the Version task of MSBuild.Community.Tasks. Just download their installer, install it, then adapt the following code and paste it after <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> in your .csproj file:

<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
<Target Name="BeforeBuild">
    <Version VersionFile="Properties\version.txt" Major="1" Minor="0" BuildType="Automatic" StartDate="12/31/2009" RevisionType="BuildIncrement">
      <Output TaskParameter="Major" PropertyName="Major" />
      <Output TaskParameter="Minor" PropertyName="Minor" />
      <Output TaskParameter="Build" PropertyName="Build" />
      <Output TaskParameter="Revision" PropertyName="Revision" />
    </Version>
    <AssemblyInfo CodeLanguage="CS"
                  OutputFile="Properties\VersionInfo.cs"
                  AssemblyVersion="$(Major).$(Minor)"
                  AssemblyFileVersion="$(Major).$(Minor).$(Build).$(Revision)" />
</Target>

Note: Adapt the StartDate property to your locale. It currently does not use the invariant culture.

For the third build on January 14th, 2010, this creates a VersionInfo.cs with this content:

[assembly: AssemblyVersion("1.0")]
[assembly: AssemblyFileVersion("1.0.14.2")]

This file then has to be added to the project (via Add existing item), and the AssemblyVersion and AssemblyFileVersion lines have to be removed from AssemblyInfo.cs.

The different algorithms for changing the version components are described in $(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.chm and Version Properties.

Solution 4

I came up with a solution similar to Christians but without depending on the Community MSBuild tasks, this is not an option for me as I do not want to install these tasks for all of our developers.

I am generating code and compiling to an Assembly and want to auto-increment version numbers. However, I can not use the VS 6.0.* AssemblyVersion trick as it auto-increments build numbers each day and breaks compatibility with Assemblies that use an older build number. Instead, I want to have a hard-coded AssemblyVersion but an auto-incrementing AssemblyFileVersion. I've accomplished this by specifying AssemblyVersion in the AssemblyInfo.cs and generating a VersionInfo.cs in MSBuild like this,

  <PropertyGroup>
    <Year>$([System.DateTime]::Now.ToString("yy"))</Year>
    <Month>$([System.DateTime]::Now.ToString("MM"))</Month>
    <Date>$([System.DateTime]::Now.ToString("dd"))</Date>
    <Time>$([System.DateTime]::Now.ToString("HHmm"))</Time>
    <AssemblyFileVersionAttribute>[assembly:System.Reflection.AssemblyFileVersion("$(Year).$(Month).$(Date).$(Time)")]</AssemblyFileVersionAttribute>
  </PropertyGroup>
  <Target Name="BeforeBuild">
    <WriteLinesToFile File="Properties\VersionInfo.cs" Lines="$(AssemblyFileVersionAttribute)" Overwrite="true">
    </WriteLinesToFile>
  </Target>

This will generate a VersionInfo.cs file with an Assembly attribute for AssemblyFileVersion where the version follows the schema of YY.MM.DD.TTTT with the build date. You must include this file in your project and build with it.

Solution 5

There is a visual studio extension Automatic Versions which supports Visual Studio (2012, 2013, 2015) 2017 & 2019.

Screen Shots enter image description here

enter image description here

Share:
230,668
ShigaSuresh
Author by

ShigaSuresh

Updated on March 24, 2020

Comments

  • ShigaSuresh
    ShigaSuresh about 4 years

    I was just wondering how I could automatically increment the build (and version?) of my files using Visual Studio (2005).

    If I look up the properties of say C:\Windows\notepad.exe, the Version tab gives "File version: 5.1.2600.2180". I would like to get these cool numbers in the version of my dll's too, not version 1.0.0.0, which let's face it is a bit dull.

    I tried a few things, but it doesn't seem to be out-of-box functionality, or maybe I'm just looking in the wrong place (as usual).

    I work with mainly web projects....

    I looked at both:

    1. http://www.codeproject.com/KB/dotnet/Auto_Increment_Version.aspx
    2. http://www.codeproject.com/KB/dotnet/build_versioning.aspx

    and I couldn't believe it so much effort to do something is standard practice.

    EDIT: It does not work in VS2005 as far I can tell (http://www.codeproject.com/KB/dotnet/AutoIncrementVersion.aspx)

  • ShigaSuresh
    ShigaSuresh over 15 years
    Yes I just encountered the ""Assembly File Version: A wildcard ("*") is not allowed in this field" that's what won your method the green tick :D
  • MusiGenesis
    MusiGenesis over 15 years
    I think for any version of VS you can only put the * in the Build or Revision boxes. I just tried this out using VS 2005, and it works fine. I'm not sure what the author of that code project article is talking about.
  • Dirk Vollmar
    Dirk Vollmar over 15 years
    Maybe it came back with a service pack, but I remember that it did not use to work when I was using VS 2005.
  • ShigaSuresh
    ShigaSuresh over 15 years
    It does not work with 2005, I'll look for a service pack and report back.
  • Dirk Vollmar
    Dirk Vollmar over 15 years
    Maybe MusiGenesis has an add-on installed which is enabling automatic versioning.
  • ShigaSuresh
    ShigaSuresh over 15 years
    This works as good as anything else, and works in VS2005. I was hoping for some rational number like 1.0.1.56 in lieu I get 1.0.3266.30135 but at least it increases (albeit by some random number :D)
  • Hath
    Hath over 15 years
    @in.spite - thats odd i have VS2005 pro and it seems to work the same as vs 2008.
  • ShigaSuresh
    ShigaSuresh over 15 years
    this works: [assembly: AssemblyVersion("1.0.*")] //[assembly: AssemblyFileVersion("1.0.0.0")]
  • ShigaSuresh
    ShigaSuresh over 15 years
    hey if I had read this properly at the beginning I would have saved myself mucho agro. thx
  • MusiGenesis
    MusiGenesis over 15 years
    @divo: no, I'm add-on-phobic. I just have Visual Studio 2005 Professional SP1. I've never seen a problem with the *, but I usually increment manually. Sounds like a weird bug.
  • Topdown
    Topdown over 14 years
    You need to do it in the AssemblyInfo.cs file as discussed. Unfortunately the "Assembly Information" dialog throws an error for our "benefit". Discussion here: connect.microsoft.com/VisualStudio/feedback/…
  • patridge
    patridge almost 13 years
    Also, within the Assembly Information IDE, make sure you either blank out anything smaller than the * in your Assembly version. It tells you you have an "invalid version format" if you don't (e.g., 0 1 * 0 => fail).
  • Philippe
    Philippe over 12 years
    It is not desirable to change the AssemblyVersion number during a release cycle. Instead, the AssemblyFileVersion should be changed. See my blog post on this topic: philippetruche.wordpress.com/2008/08/12/… Also see Suzanne Cook's excellent post on when to change the numbers: blogs.msdn.com/b/suzcook/archive/2003/05/29/57148.aspx
  • David Faivre
    David Faivre over 12 years
    Nice call on needing to remove the AssemblyFileVersion attribute to get this to work!
  • Shambhu Kumar
    Shambhu Kumar over 12 years
    I'd be careful using the * it will stop working on June 4th 2179 when the day becomes 65536
  • Andres Scarpone
    Andres Scarpone about 12 years
    This is the best way yet that I've seen to get around the awful fact that FileVersion structs use 16 bit integers.
  • Xcalibur
    Xcalibur about 12 years
    @0xA3 I believe the MSDN link you are referring to is support.microsoft.com/kb/556041
  • DaveO
    DaveO over 11 years
    I had issues installing into VS2012 using the Package Console so recommend using the downloaded nightly msi installers at github.com/loresoft/msbuildtasks/downloads. Works copy/paste from the above. Thanks!
  • onefootswill
    onefootswill over 11 years
    I realise this is an old question, but wanted to add this comment for others who find their way to this answer. If you increment the AssemblyVersion, any project that uses your dll will need to be re-compiled. However, if you keep the AssemblyVersion the same and increment the AssemblyFileVersion by itself, then you can swap the new dll in without having to re-compile whatever is using it. So ask yourself this, is this just a new build, or am I releasing a new version?
  • radu florescu
    radu florescu over 11 years
    After it was denied and edit on this post: "You may also want to check this loresoft.com/projects/msbuildtasks/… it can improve the basic functionality described before."
  • Cristian Diaconescu
    Cristian Diaconescu about 11 years
    @DD59 the 'Build' is number of days since Jan 1st 2000; the 'Revision' is seconds from midnight divided by 2 (not half-seconds, but two-second intervals). See here: stackoverflow.com/a/3387167/11545
  • JDennis
    JDennis almost 10 years
    This is not a viable solution for those who build with TFS. Ultimatey, this will add a pending edit to the VersionInfo.cs and version.txt files. For me, it is not desirable to have a pending edit for each build.
  • Огњен Шобајић
    Огњен Шобајић over 9 years
    The VS is in charge of incrementing the last number which is usually the build number. Everything else (i.e. the numbers before that) is up to you because they represent the version of your application.
  • Sinaesthetic
    Sinaesthetic over 9 years
    @onefootswill but how would you increment the file version separate from the the assembly version if you can only have one of them specified?
  • onefootswill
    onefootswill over 9 years
    @Sinaesthetic I guess you couldn't iif you can only have one specified. But I've never seen a restriction like that. In the Assembly.cs or the SharedAssemblyInfo.cs (as the case may be), you can always specify both.
  • Nicolas Fall
    Nicolas Fall over 8 years
    any ideas why this works locally in visual studio, but I seem to be getting 1.0.0.0 in TFS 2010 builds?
  • Christian
    Christian over 8 years
    @JDennis see here for TFS versioning tips...
  • Simon Tewsi
    Simon Tewsi almost 8 years
    Огњен Шобајић: Not quite right. Microsoft's numbering scheme is major.minor.build.revision, eg 1.0.4.7. If you set the assembly version to something like "1.0.*" then VS will set the build and revision numbers for you. In that case build will increment daily, and revision will be the number of seconds since midnight, divided by 2.
  • Unbreakable
    Unbreakable over 7 years
    How these 3266,92689 two numbers got generated in. 1.0.3266.92689
  • Maxim
    Maxim about 7 years
    So I have uninstalled it and I can say even more... it modifies original csproj file. I think it is very problematic extension.
  • Rady
    Rady about 7 years
    @Maxim Try latest version, it should work on VS 2017
  • Justine Krejcha
    Justine Krejcha almost 7 years
    @Unbreakable 3266 is the number of days since 1-1-2000, 92689 is the amount of two second intervals from midnight.
  • Edward Brey
    Edward Brey almost 7 years
    Does MSBuild support variables? It would be better to put [System.DateTime]::Now into one, otherwise, there's a race condition that can cause an old build number to be used if building near midnight.
  • Ian
    Ian over 6 years
    @JustinKrejcha And yet there are only 86400 seconds in 24 hours... <twilight zone music>
  • Shimmy Weitzhandler
    Shimmy Weitzhandler over 6 years
    How can this be achieved in the new csproj format where there is no AssemblyInfo.cs?
  • Michael Freidgeim
    Michael Freidgeim over 6 years
    @Shimmy: Add <Deterministic>False</Deterministic> to .csproj Auto Versioning in Visual Studio 2017 (.NET Core)
  • kara
    kara over 6 years
    @Ian two-second-intervals. Max would be 43199 at 23:59:59. The Year 3266 would be something in 2008. I guess that Sam chose some random numbers.
  • AaA
    AaA about 6 years
    Your number is gonna run out fast. I would use yyddd which is 2 digit year and 3 digit day from start of year which is max 365. at least your program would compile until year 2065. then you would be retired and let someone else figure out how they want to handle it. given your program is still in commission at that date!
  • AaA
    AaA about 6 years
    The only problem with PS is it is slow to react and requires configuration to allow it to run. I would go with a small executable, a tt4 file or even inline code which I think any programmer can write in one way.
  • mafu
    mafu about 6 years
    Did you define these four properties instead of combining them in a single DateTime.ToString for demonstrative purposes, or is there a particular reason?
  • afterxleep
    afterxleep over 5 years
    Excellent! This was so useful to me that I blogged it: pretty much the same instructions as above but with some screenshots to demonstrate: technical-recipes.com/2018/…
  • Rhys Jones
    Rhys Jones almost 5 years
    If your BeforeBuild event doesn't fire in VS2017 check out stackoverflow.com/questions/43921992/…
  • Cary
    Cary almost 5 years
    It works perfectly. However, this regular expression %date:~-4,4%.%date:~-7,2%%date:~-10,2%.%time:~0,2%%time:~3,2‌​%.%time:~-5,2%" is just too complicated.
  • Cary
    Cary almost 5 years
    This solution is the best fit out of all the answers here. However, the problem is, the timestamp (or the content of the versioninfo.cs file) does not update if you build the project for the second time which should produce a different minute. If I close and reload the project, then the timestamp gets updated. Is this a bug from MSBuild? @Boog
  • err1
    err1 over 4 years
    Excellent util. Works fine for me in vs2017. Docs could be slightly clearer, but install it (via the site) and then install MSBuild via Nuget, apply to a small project and play and build. Nice. @Boog's answer didn't work for me although he said exactly what I was trying to achieve.
  • sinsedrix
    sinsedrix over 3 years
    Is this possible to make any operation in these markups? With $([System.DateTime]::Today.Year - 2010), I get an error unable to evaluate expression ""24/08/2020 00:00:00".Year - 2010". Cannot find method 'SystemDateTime.Year -2009'.
  • Stelios Adamantidis
    Stelios Adamantidis about 3 years
    That's an excellent solution for someone who wants to follow calver! +1 from me. One thing I would simplify is the variables: <Date>$([System.DateTime]::Now.ToString("yyyy.M.d.HHmm"))</D‌​ate>. Works like a charm.
  • Missy
    Missy almost 3 years
    Yes! I love this product!!
  • Tobias Knauss
    Tobias Knauss over 2 years
    @LloydPowell: MS Excel tells me "June 6th", so at your date you have 2 days left to find a workaround ;-) And don't forget to tell your grandchildren about that issue.
  • Chris W
    Chris W almost 2 years
    @Lloyd Powell, you made my day :D +1 !
  • Shambhu Kumar
    Shambhu Kumar almost 2 years
    @ChrisW I'm glad my 'banter' from 11 years ago is still providing entertainment for the .net community :-)
  • Chris W
    Chris W almost 2 years
    @LloydPowell Yeah, it's kinda timeless. Almost :D