As a continuation of MikeS's answer I wanted to add that VS + Visual Studio Visualization and Modeling SDK needs to be installed for this to work, and you need to modify the project file as well. Should also be mentioned I use Jenkins as build server running on a windows 2008 R2 server box with version module, where I get the BUILD_NUMBER.
My Text Template file version.tt looks like this
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<#
var build = Environment.GetEnvironmentVariable("BUILD_NUMBER");
build = build == null ? "0" : int.Parse(build).ToString();
var revision = Environment.GetEnvironmentVariable("_BuildVersion");
revision = revision == null ? "5.0.0.0" : revision;
#>
using System.Reflection;
[assembly: AssemblyVersion("<#=revision#>")]
[assembly: AssemblyFileVersion("<#=revision#>")]
I have the following in the Property Groups
<PropertyGroup>
<TransformOnBuild>true</TransformOnBuild>
<OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
<TransformOutOfDateOnly>false</TransformOutOfDateOnly>
</PropertyGroup>
after import of Microsoft.CSharp.targets, I have this (dependant of where you install VS
<Import Project="C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\TextTemplating\v10.0\Microsoft.TextTemplating.targets" />
On my build server I then have the following script to run the text transformation before the actual build, to get the last changeset number on TFS
set _Path="C:\Build_Source\foo"
pushd %_Path%
"%ProgramFiles(x86)%\Microsoft Visual Studio 10.0\Common7\IDE\tf.exe" history . /r /noprompt /stopafter:1 /Version:W > bar
FOR /f "tokens=1" %%foo in ('findstr /R "^[0-9][0-9]*" bar') do set _BuildVersion=5.0.%BUILD_NUMBER%.%%foo
del bar
popd
echo %BUILD_NUMBER%
echo %_BuildVersion%
cd C:\Program Files (x86)\Jenkins\jobs\MyJob\workspace\MyProject
MSBuild MyProject.csproj /t:TransformAll
...
<rest of bld script>
This way I can keep track of builds AND changesets, so if I haven't checked anything in since last build, the last digit should not change, however I might have made changes to the build process, hence the need for the second last number. Of course if you make multiple check-ins before a build you only get the last change reflected in the version. I guess you could concatenate of that is required.
I'm sure you can do something fancier and call TFS directly from within the tt Template, however this works for me.
I can then get my version at runtime like this
Assembly assembly = Assembly.GetExecutingAssembly();
FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
return fvi.FileVersion;