Programmatically detect your Team Foundation Server version

I have already spent quite a lot of time using the new TFS 11 Beta API. One of the most interesting new features in the upcoming version is the introduction of Teams and the project-management stuff. Now, when you connect to a TFS server programmatically, you might need or want to know the exact server version, especially if you are developing code that should work with multiple versions, ranging from TFS 2005 to TFS 11.

So, here’s one way to do it. First, create an enumeration that will represent the server version:

enum TfsVersion
{
    Tfs2008,
    Tfs2010,
    Tfs2011
}

Next, implement an extension method on the TfsTeamProjectCollection class:

internal static class TfsTeamProjectCollectionEx
{
	internal static TfsVersion GetVersion(this TfsTeamProjectCollection coll)
	{
		if (coll == null)
			throw new ArgumentNullException("coll");
	
		if (coll.ConfigurationServer == null)
			return TfsServerVersion.Tfs2008;
	
		try
		{
			TfsTeamService teamService = coll.GetService<TfsTeamService>();
			teamService.QueryTeams(string.Empty);
			return TfsServerVersion.Tfs2011;
		}
		catch
		{
			return TfsServerVersion.Tfs2010;
		}
	}
}

And there you go. As you may have noticed, I deliberately don’t distinguish between TFS 2005 and TFS 2008 because I’ve never actually needed to. In TFS 2010, the concept of team project collections was introduced and this is why we can use the ConfigurationServer property of TfsTeamProjectCollection to distinguish between TFS 2010 and older versions. You can read more about the TfsConfigurationServer here and here.

What’s more interesting is the distinction between TFS 2010 and TFS 11 versions. Since the Teams functionality and hence the TfsTeamService is implemented on TFS 11 only, I expected that calling GetService<TfsTeamService>() would result in a TfsServiceUnavailable (or similar) exception. Instead, even on TFS 2010 servers, you get an instance of the TfsTeamService class. However, calling QueryTeams() and passing in an empty string results in an exception on TFS 2010 and returns an empty TeamFoundationTeam[] object in TFS 11.

Do you know a better or more reliable way? Interested in other TFS 11 API stuff? Let me know!

Be Sociable, Share!
  • http://blogs.msdn.com/buckh Buck Hodges

    Ivan, I’d suggest just checking for the feature you need. The difference is that by checking for the feature you need when you need it (and perhaps caching it for perf) is that you aren’t making assumptions about the features not changing for an entire release or having to update it for future releases (e.g., the GetVersion() method would need to be updated every time a new one ships). If we add features in a patch or service pack, this approach quickly becomes problematic.

    Buck

  • Ivan Popek

    Buck, this is exactly the kind of feedback I was hoping for :)

    You make a good point there. What I’ve also found myself (after writing this post), is that the ‘version’ of the server is not as important as the features that are available. I’ve realized this when I’ve discovered a few subtleties between the on-premise TFS 11 installation and the TfsPreview service, which are both TFS 11 servers, technically. Then you start having IsTfsPreview() methods and things get really ugly really fast :)

    Thanks for sharing!