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:
http://www.codeproject.com/KB/dotnet/Auto_Increment_Version.aspx
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)
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
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.
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.
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.
There is a visual studio extension Automatic Versions which supports Visual Studio (2017,2019 & 2022)
Screen Shots
Install the Build Version Increment add-in. It gives you way more control than the * option.
To get the version numbers try
System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
System.Reflection.AssemblyName assemblyName = assembly.GetName();
Version version = assemblyName.Version;
To set the version number, create/edit AssemblyInfo.cs
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("1.0.*")]
Also as a side note, the third number is the number of days since 2/1/2000 and the fourth number is half of the amount of total seconds in the day. So if you compile at midnight it should be zero.
In Visual Studio 2019
It was not enough for me adding
[assembly: AssemblyVersion("1.0.*")]
When building it throws me this error
The specified version string does not conform to the required format
Solution
The format was finally accepted after I set Deterministic to False in project.csproj
<Deterministic>false</Deterministic>
Edit:
For some reason setting Deterministic to False messed up my config file loading it and saving it on different locations.
Workaround:
I setup a post-build event to increment the revision number:
Post-Build Event batch script
This calls a powershell script named autoincrement_version.ps1 passing as argument the path of AssemblyInfo.cs
if $(ConfigurationName) == Release (
PowerShell -ExecutionPolicy RemoteSigned $(ProjectDir)autoincrement_version.ps1 '$(ProjectDir)My Project\AssemblyInfo.cs'
)
Poweshell script
It autoincrements the revision number using Regex
param( [string]$file );
$regex_revision = '(?<=Version\("(?:\d+\.)+)(\d+)(?="\))'
$found = (Get-Content $file) | Select-String -Pattern $regex_revision
$revision = $found.matches[0].value
$new_revision = [int]$revision + 1
(Get-Content $file) -replace $regex_revision, $new_revision | Set-Content $file -Encoding UTF8
Setting a * in the version number in AssemblyInfo or under project properties as described in the other posts does not work with all versions of Visual Studio / .NET.
Afaik it did not work in VS 2005 (but in VS 2003 and VS 2008). For VS 2005 you could use the following: Auto Increment Visual Studio 2005 version build and revision number on compile time.
But be aware that changing the version number automatically is not recommended for strong-named assemblies. The reason is that all references to such an assembly must be updated each time the referenced assembly is rebuilt due to the fact that strong-named assembly references are always a reference to a specific assembly version. Microsoft themselves change the version number of the .NET Framework assemblies only if there are changes in interfaces. (NB: I'm still searching for the link in MSDN where I read that.)
To get incrementing (DateTime) information into the AssemblyFileVersion property which has the advantage of not breaking any dependencies.
Building on Boog's solution (did not work for me, maybe because of VS2008?), you can use a combination of a pre-build event generating a file, adding that file (including its version properties) and then using a way to read out those values again. That is..
Pre-Build-Event:
echo [assembly:System.Reflection.AssemblyFileVersion("%date:~-4,4%.%date:~-7,2%%date:~-10,2%.%time:~0,2%%time:~3,2%.%time:~-5,2%")] > $(ProjectDir)Properties\VersionInfo.cs
Include the resulting VersionInfo.cs file (Properties subfolder) into your project
Code to get Date back (years down to seconds):
var version = assembly.GetName().Version;
var fileVersionString = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location).FileVersion;
Version fileVersion = new Version(fileVersionString);
var buildDateTime = new DateTime(fileVersion.Major, fileVersion.Minor/100, fileVersion.Minor%100, fileVersion.Build/100, fileVersion.Build%100, fileVersion.Revision);
Not very comfortable.. also, I do not know if it creates a lot of force-rebuilds (since a file always changes).
You could make it smarter for example if you only update the VersionInfo.cs file every few minutes/hours (by using a temporary file and then copying/overwriting the real VersionInfo.cs if a change large enough is detected). I did this once pretty successfully.
Set the version number to "1.0.*" and it will automatically fill in the last two number with the date (in days from some point) and the time (half the seconds from midnight)
It is in your project properties under Publish
(~ http://screencast.com/t/Vj7rhqJO)
Cake supports AssemblyInfo files patching. With cake in hands you have infinite ways to implement automatic version incrementing.
Simple example of incrementing version like C# compiler does:
Setup(() =>
{
// Executed BEFORE the first task.
var datetimeNow = DateTime.Now;
var daysPart = (datetimeNow - new DateTime(2000, 1, 1)).Days;
var secondsPart = (long)datetimeNow.TimeOfDay.TotalSeconds/2;
var assemblyInfo = new AssemblyInfoSettings
{
Version = "3.0.0.0",
FileVersion = string.Format("3.0.{0}.{1}", daysPart, secondsPart)
};
CreateAssemblyInfo("MyProject/Properties/AssemblyInfo.cs", assemblyInfo);
});
Here:
Version - is assembly version. Best practice is to lock major version number and leave remaining with zeroes (like "1.0.0.0").
FileVersion - is assembly file version.
Note that you can patch not only versions but also all other necessary information.
How to get the version {major}.{year}.1{date}.1{time}
This one is kind of experimental, but I like it. Inspired by Jeff Atwood # CodingHorror (link).
The resulting version number becomes 1.2016.10709.11641 (meaning 2016-07-09 16:41), which allows for
poor mans zero padding (with the stupid leading 1s)
nearly-human readable local DateTime embedded into the version number
leaving Major version alone for really major breaking changes.
Add a new item to your project, select General -> Text Template, name it something like CustomVersionNumber and (where applicable) comment out the AssemblyVersion and AssemblyFileVersion in Properties/AssemblyInfo.cs.
Then, when saving this file, or building the project, this will regenerate a .cs file located as a sub-item under the created .tt file.
<## template language="C#" #>
<## assembly name="System.Core" #>
<## import namespace="System.Linq" #>
//
// This code was generated by a tool. Any changes made manually will be lost
// the next time this code is regenerated.
//
using System.Reflection;
<#
var date = DateTime.Now;
int major = 1;
int minor = date.Year;
int build = 10000 + int.Parse(date.ToString("MMdd"));
int revision = 10000 + int.Parse(date.ToString("HHmm"));
#>
[assembly: AssemblyVersion("<#= $"{major}.{minor}.{build}.{revision}" #>")]
[assembly: AssemblyFileVersion("<#= $"{major}.{minor}.{build}.{revision}" #>")]
Go to Project | Properties and then Assembly Information and then Assembly Version and put an * in the last or the second-to-last box (you can't auto-increment the Major or Minor components).
Use the AssemblyInfo task from the MSBuild Community Tasks (http://msbuildtasks.tigris.org/) project, and integrate it into your .csproj/.vbproj file.
It has a number of options, including one to tie the version number to the date and time of day.
Recommended.
As of right now, for my application,
string ver = Application.ProductVersion;
returns ver = 1.0.3251.27860
The value 3251 is the number of days since 1/1/2000. I use it to put a version creation date on the splash screen of my application. When dealing with a user, I can ask the creation date which is easier to communicate than some long number.
(I'm a one-man dept supporting a small company. This approach may not work for you.)
Maybe, for this task, you can use code like this:
private bool IncreaseFileVersionBuild()
{
if (System.Diagnostics.Debugger.IsAttached)
{
try
{
var fi = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory).Parent.Parent.GetDirectories("Properties")[0].GetFiles("AssemblyInfo.cs")[0];
var ve = System.Diagnostics.FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location);
string ol = ve.FileMajorPart.ToString() + "." + ve.FileMinorPart.ToString() + "." + ve.FileBuildPart.ToString() + "." + ve.FilePrivatePart.ToString();
string ne = ve.FileMajorPart.ToString() + "." + ve.FileMinorPart.ToString() + "." + (ve.FileBuildPart + 1).ToString() + "." + ve.FilePrivatePart.ToString();
System.IO.File.WriteAllText(fi.FullName, System.IO.File.ReadAllText(fi.FullName).Replace("[assembly: AssemblyFileVersion(\"" + ol + "\")]", "[assembly: AssemblyFileVersion(\"" + ne + "\")]"));
return true;
}
catch
{
return false;
}
}
return false;
}
and call it from form loading.
With this code you can update any part of file info in AssemblyInfo.cs (but you must use "standard" directory structure).
Changing the AssemblyInfo works in VS2012. It seems strange that there's not more support for this in Visual Studio, you'd think this was a basic part of the build/release process.
I have created an application to increment the file version automatically.
Download Application
add the following line to pre-build event command line
C:\temp\IncrementFileVersion.exe $(SolutionDir)\Properties\AssemblyInfo.cs
Build the project
To keep it simple the app only throws messages if there is an error, to confirm it worked fine you will need to check the file version in 'Assembly Information'
Note : You will have to reload the solution in Visual studio for 'Assembly Information' button to populate the fields, however your output file will have the updated version.
For suggestions and requests please email me at telson_alva#yahoo.com
AssemblyInfoUtil. Free. Open-source.
I'm using this approach https://stackoverflow.com/a/827209/3975786 by placing the T4 template in a "Solution Items" and using it with "Add as Link" within each project.
Maybe it's too late to answer here but hope that will solve someone's hectic problem.
An automatic way to change assembly version of all of your projects using PowerShell script. This article will solve many of your problems.
I tried this with Visual Studio 2019 and it did not work.
In newer versions of VS at least the Deterministic-flag prevents the auto-update. But changing the 14th line of
Your-project-name.csproj to <Deterministic>false</Deterministic>
and changing the version number string to "1.0.*" did not help me.
So I made a litle vbs script that does the job.
it changes the version number to (Major version).(Minor version).([year][dayofyear]).(increment).
Copy the script into a folder and put the following into pre-compile build-commandline:
"Path-to-this-script\UpdateVersion.vbs" "$(ProjectDir)"
(including the quotes and filling in the real path of Your machine)
and You are done.
Get it here:
https://github.com/abtzero/VS_UpdateVersion.git
Each time I do a build it auto-increments the least-significant digit.
I don't have any idea how to update the others, but you should at least be seeing that already...
For anyone using Tortoise Subversion, you can tie one of your version numbers to the subversion Revision number of your source code. I find this very useful (Auditors really like this too!). You do this by calling the WCREV utility in your pre-build and generating your AssemblyInfo.cs from a template.
If your template is called AssemblyInfo.wcrev and sits in the normal AssemblyInfo.cs directory, and tortoise is in the default installation directory, then your Pre-Build command looks like this (N.B. All on one line):
"C:\Program Files\TortoiseSVN\bin\SubWCRev.exe" "$(ProjectDir)." "$(ProjectDir)Properties\AssemblyInfo.wcrev" "$(ProjectDir)Properties\AssemblyInfo.cs"
The template file would include the wcrev token substitution string: $WCREV$
e.g.
[assembly: AssemblyFileVersion("1.0.0.$WCREV$")]
Note:
As your AssemblyInfo.cs is now generated you do not want it version controled.
Related
I have a windows forms application that is deployed to two different locations.
Intranet - ClickOnce
Internet - Installed on a citrix farm through Windows installer
I display ClickOnce version number for click-once deployed versionApplicationDeployment.IsNetworkDeployed.
if (ApplicationDeployment.IsNetworkDeployed)
return ApplicationDeployment.CurrentDeployment.CurrentVersion;
But for the non-click application, I am not sure how to retrieve clickonce version unless I hardcode the version number in assembly info.
Is there an automatic way of retrieve ClickOnce version number for non-clickonce deployed version?
Add an assembly reference to System.Deployment to your project.
Import the namespace in your class file:
VB.NET:
Imports System.Deployment.Application
C#:
using System.Deployment.Application;
Retrieve the ClickOnce version from the CurrentVersion property.
You can obtain the current version from the ApplicationDeployment.CurrentDeployment.CurrentVersion property. This returns a System.Version object.
Note (from MSDN):
CurrentVersion will differ from UpdatedVersion if a new update has
been installed but you have not yet called Restart. If the deployment
manifest is configured to perform automatic updates, you can compare
these two values to determine if you should restart the application.
NOTE: The CurrentDeployment static property is only valid when the application has been deployed with ClickOnce. Therefore before you access this property, you should check the ApplicationDeployment.IsNetworkDeployed property first. It will always return a false in the debug environment.
VB.NET:
Dim myVersion as Version
If ApplicationDeployment.IsNetworkDeployed Then
myVersion = ApplicationDeployment.CurrentDeployment.CurrentVersion
End If
C#:
Version myVersion;
if (ApplicationDeployment.IsNetworkDeployed)
myVersion = ApplicationDeployment.CurrentDeployment.CurrentVersion;
Use the Version object:
From here on you can use the version information in a label, say on an "About" form, in this way:
VB.NET:
versionLabel.Text = String.Concat("ClickOnce published Version: v", myVersion)
C#:
versionLabel.Text = string.Concat("ClickOnce published Version: v", myVersion);
(Version objects are formatted as a four-part number (major.minor.build.revision).)
No I do not believe that there is a way. I believe the ClickOnce information comes from the manifest which will only be available in a ClickOnce deployment. I think that hard coding the version number is your best option.
I would simply make the assembly version of the main assembly the same as the CLickOnce version every time you put out a new version. Then when it runs as a non-clickonce application, just use Reflection to pick up the assembly version.
Try thread verification:
if (ApplicationDeployment.IsNetworkDeployed)
{
if (ApplicationDeployment.CurrentDeployment.CurrentVersion != ApplicationDeployment.CurrentDeployment.UpdatedVersion)
{
Application.ExitThread();
Application.Restart();
}
}
not that it matters three years later, but I ended up just parsing the manifest file with xml reader.
To expand on RobinDotNet's solution:
Protip: You can automatically run a program or script to do this for you from inside the .csproj file MSBuild configuration every time you build. I did this for one Web application that I am currently maintaining, executing a Cygwin bash shell script to do some version control h4x to calculate a version number from Git history, then pre-process the assembly information source file compiled into the build output.
A similar thing could be done to parse the ClickOnce version number out of the project file i.e., Project.PropertyGroup.ApplicationRevision and Project.PropertyGroup.ApplicationVersion (albeit I don't know what the version string means, but you can just guess until it breaks and fix it then) and insert that version information into the assembly information.
I don't know when the ClickOnce version is bumped, but probably after the build process so you may need to tinker with this solution to get the new number compiled in. I guess there's always /*h4x*/ +1.
I used Cygwin because *nix scripting is so much better than Windows and interpreted code saves you the trouble of building your pre-build program before building, but you could write the program using whatever technology you wanted (including C#/.NET). The command line for the pre-processor goes inside the PreBuildEvent:
<PropertyGroup>
<PreBuildEvent>
$(CYGWIN_ROOT)bin\bash.exe --login -c refresh-version
</PreBuildEvent>
</PropertyGroup>
As you'd imagine, this happens before the build stage so you can effectively pre-process your source code just before compiling it. I didn't want to be automatically editing the Properties\AssemblyInfo.cs file so to play it safe what I did was create a Properties\VersionInfo.base.cs file that contained a text template of a class with version information and was marked as BuildAction=None in the project settings so that it wasn't compiled with the project:
using System.Reflection;
using EngiCan.Common.Properties;
[assembly: AssemblyVersion("0.$REVNUM_DIV(100)$.$REVNUM_MOD(100)$.$DIRTY$")]
[assembly: AssemblyRevisionIdentifier("$REVID$")]
(A very dirty, poor-man's placeholder syntax resembling Windows' environment variables with some additional h4x thrown in was used for simplicity's/complexity's sake)
AssemblyRevisionIdentifierAttribute was a custom attribute that I created to hold the Git SHA1 since it is much more meaningful to developers than a.b.c.d.
My refresh-version program would then copy that file to Properties\VersionInfo.cs, and then do the substitution of the version information that it already calculated/parsed (I used sed(1) for the substitution, which was another benefit to using Cygwin). Properties\VersionInfo.cs was compiled into the program. That file can start out empty and you should ignore it by your version control system because it is automatically changing and the information to generate it is already stored elsewhere.
Hard code, or... Keep track on your versions (File, Assembly, Deploy) in a database. Make a call to the database with your Assembly and get the Deploy version.
This assumes that you are incrementing your versions in a logical way such that each version type has a relationship. It's a lot of work for such a minor problem. I'd personally go with Jared's solution; although I hate hard coding anything.
Using a build component, you could read the click-once version from the project file and write it automatically to the assembly info so both of them are in sync.
Solution for .NET (Core) 7 and higher
On .net Core, you can read the version number from the environment variable ClickOnce_CurrentVersion.
string versionString = Environment.GetEnvironmentVariable("ClickOnce_CurrentVersion") ?? "0.0.0.0";
Version version= Version.Parse(versionString);
MessageBox.Show(version.ToString());
See documentation
I can see the 140 in my csproj file.
How do I read and display this number in my application.
I tried
System.Deployment.Application.ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString()
But it did not work
And I have one more question, why the related article always said ApplicationDeployment.IsNetworkDeployed
But I have to call "System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed"
Did I miss some thing??
You can get the version number that is set in the executing AssemblyInfo.cs using this code
System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()
You can get further information about on the above code from the following link:
How to show application version in VS.NET Deployment Project?
Find the file Properties/AssemblyInfo.cs
Manually alter the version
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.2.0.0")]
[assembly: AssemblyFileVersion("1.3.0.0")]
It works!!
I have a solution with over 30 projects in it... Is there a quick and easy way of managing the build revision of all projects rather than editing the AssemblyInfo or Properties of each one?
In the past, I've followed the advice in this article to create a SharedAssemblyInfo.cs file at the solution level and linked to it from each of my projects.
The main point is that you want to add the SharedAssemblyInfo.cs file to your projects as a link. In Visual Studio, you would choose "Add Existing Item", but in the dialog, click the arrow on the Add button and select "Add As Link".
In SharedAssemblyInfo.cs, put any assembly attributes that you want to be the same across all projects. The article recommends the following:
AssemblyCompany
AssemblyProduct
AssemblyCopyright
AssemblyTrademark
AssemblyConfiguration
AssemblyDescription
CLSCompliant
ComVisible
AssemblyVersion
AssemblyInformationalVersion
Each project will still have its own AssemblyInfo.cs file as well to supplement the attribute it receives from the shared file:
AssemblyTitle
AssemblyCulture
Guid
I recommend using AssemblyInfo Task,
http://archive.msdn.microsoft.com/AssemblyInfoTaskvers
[Updated: it is an MSBuild targets from Microsoft MSBuild team. No Visual Studio addin is needed, so it works fine even if you use MSBuild directly.]
You can use its targets to modify a central AssemblyInfo.cs file and then link it to all projects. My open source project #SNMP shows how it is utilized,
https://github.com/lextm/sharpsnmplib
Normally this should be only a comment, but I want to give this as an answer
This addin for VS is a real lifesaver
Versioning Controlled Build
I'm so fond of this addin that I'm using it from the VS 2003 version.
Just pay attention and read all the article, there are some hiccups when other addins are installed
While the accepted answer is really good, I still prefer to have, for each project a separated assemblyinfo.cs, containing the FileVersion and AssemblyVersion attribute, because, in this way, I can increment these values separately, when there is a bug fix or a revision to distribute
I'm in the process of learning TFS2010 Team Build, Workflow and MSBuild. I've got a general understanding of Workflow and was recently able to do a successful test build.
Now I need some help with keeping build version and assembly versioning in sync. I've been reading several blogs by Jim Lamb and John Robbins on this subject however I'm feeling more confused now than when I started. Jim Lamb's blogs talk about using a custom activity which uses the current date to set the version number and John Robbins' blog talks about getting the last assembly version and doing everything in MSBuild since there are no extra dependencies.
Currently we are using a 4 place version number such as 3.8.0.2 then we increment the last number for each build. We use this version to synce all the assemblies. We would like to stay with this format and I'd like to handle all my versioning in workflow however I don't know how to read the last version from an assembly that way. I'm thinking this will require writing a custom activity but what method would I use to read last version?
Thanks in advance!
Jim
Stuart Preston explains a simple way to set the assembly info on his blog:
http://stuartpreston.net/blog/2010/05/02/simple-assembly-versioning-with-team-build-2010/
Edit:
Above link is dead, here is the cached version:
Posted by Stuart Preston on May 2, 2010 under Team Foundation Server
There are many more sophisticated ways of achieving this but none seemed to give me exactly what I wanted, so here I present yet another way of doing assembly versioning with Team Build 2010. I wanted my Team Build number to exactly match that of my assembly versions (and not be derived), like this:
(image)
So here’s how I do it. To start off with I customise the BuildNumber format within my build definition:
(image)
In my case, I decided to customize it so that the Major and Minor version numbers “0.1” were added explicitly. This lets me control the first two parts of the version number which is what I want to achieve. I also added the macros $(Month)$(DayOfMonth) with a 1 in front of it. For the 2nd May 2010 this would generate a number 10502. (The reason I don’t use the full year here is that for today it would generate a build number of 100502 and a file version number cannot be higher than 65335).
When I decide to work on version 0.2, 0.3 or 1.0 all I have to do is increment the Build Number here and save the definition, I’m also happy to increment the number when the year changes. I said it was simple!
The final part of the build number format was left as-is (i.e. the Revision number that increments by 1 with each build on that day and resets for the next day).
Now all we need to do is retrieve this version number when MSBuild is run against the solution, split the version number and take the numeric portion into the Properties\AssemblyVersion.cs file (you will need to comment out the AssemblyFileVersion line in that file first and check it in).
Here’s the fragment that you’ll need to insert in your .csproj file (you’ll have to check it out then open it in Notepad or your favourite text editor).
<UsingTask
TaskName="Microsoft.TeamFoundation.Build.Tasks.GetBuildProperties"
AssemblyFile="$(MSBuildProgramFiles32)\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\Microsoft.TeamFoundation.Build.ProcessComponents.dll"
Condition="' $(BuildUri) '!=' '"/>
<Target Name="BeforeBuild" Condition="' $(BuildUri) '!=' '">
<GetBuildProperties TeamFoundationServerUrl="$(TeamFoundationServerUrl)" BuildUri="$(BuildUri)">
<Output TaskParameter="BuildNumber" PropertyName="BuildNumber" />
</GetBuildProperties>
<PropertyGroup>
<BuildNumberSplitLocation>$([MSBuild]::Add($(BuildNumber.LastIndexOf('_')),1))</BuildNumberSplitLocation>
</PropertyGroup>
<ItemGroup>
<AssemblyVersionLines Include="[assembly:AssemblyFileVersion("$(BuildNumber.Substring($(BuildNumberSplitLocation)))")]" />
</ItemGroup>
<Exec Command="attrib -r "$(ProjectDir)\Properties\AssemblyInfo.cs"" ContinueOnError="false" />
<Message Text="Lines being added: #(AssemblyVersionLines)" Importance="high" />
<WriteLinesToFile File="$(ProjectDir)\Properties\AssemblyInfo.cs" Lines="#(AssemblyVersionLines)" />
</Target>
(End of reference)
He modifies the csproj file to update the AssemblyInfo.cs file before build with values passed in by TFS so that the assembly is versioned according to a permutation of MMDDRev
Your situation is a bit different in that you'd like a custom build number. To do that, you could modify the BuildNumberFormat to be 3.8.0.$(Rev:.r). Since the revision is the only thing changing, TFS will automagically increment it for you.
If you ever want to update the 3.8.0. portion, you can again edit the Build Number Format manually. Otherwise you'll need a solution for storing & parsing the build number as part of the BeforeBuild task in your csproj.
i have just started at a new company where i am basically looking after solution builds using TFS 2010. i have added a few new custom activities to increase version numbers in the AssemblyInfo files of the projects and this is working fine. The problem im finding is that all AssemblyInfo.cs files have the AssemblyVersion and AssemblyFileVersion numbers, but only some have an AssemblyInformationVersion number aswell. Can anyone please tell me what causes the AssemblyInformationVersion to appear in some AssemblyInfo.cs files and not others?
Thanks
[AssemblyInformationalVersion] is an optional attribute that maps to the ProductVersion property of the application. If it is not present, the value specified in the [AssemblyVersion] attribute is used instead.
As far as I can tell, Visual Studio never adds [AssemblyInformationalVersion] attributes to the AssemblyInfo.cs files it generates. The developers might have added those if they wanted the product version to be different from the assembly version in some of your projects.