Community TFS 2010 Build Extensions–September Release


The Community TFS Build Extensions just released a new version, these are a set of Team Build WF Activities that will ease the work of build masters. It has a over 100 activities that range from file activities, VMs (Hyper-V and Virtual PC, TFS objects manipulation, VB6 compiling, IIS7, code metrics, stylecop,assembly info file manipulation and powershell execution  (to name just a few).

You can read announcement in Mike Fourie’s post.

The maintainers were foolish enough to include in the latest release an activity that I wrote to build and deploy code using Visual Studio, but that is material for a soon to be published blog post.

You can go to the Codeplex project site to download the binaries or the source code.

Give Feedback to the Visual Studio Team


In the past the most appropriate way you could give feedback to the Visual Studio team would be to use MS Connect (if you don’t count comments on the numerous VS team blogs, and posts on the MSDN forums which are mainly for asking questioos). Although connect can be used to give feedback and make requests it is mainly a way to report Bugs.

So the Visual Studio is now giving us yet another method to post feedback. An UserVoice site, UserVoice is more social (forums are also pretty social but in a different way) since not only allows you to post suggestions, but allows people to comment on it and better yet to vote on it. The most popular suggestions will percolate through their number of votes making them more visible to the team (which even so reads and analyzes all suggestions no matter how many votes they get).

The most voted a suggestion is the most probability it has of being implemented. Smile

Keep in mind that this site should be used mainly for feature suggestions rather than reporting bugs. For reporting bugs Connect is the more appropriate place to report bugs.

Getting Visual Studio version of a Solution file

In the previous post I talked about how we could determine the installation path of a given Visual Studio version, in this post I’m going to talk a little how we can determine the version of a VS solution file (.sln).

Determining the file version isn’t of relevance if you are opening solutions via the file explorer. If you have multiple versions of VS installed side by side and try to open a solution, the VS Version selector automatically chooses the right visual studio version for you.

However if you intend to automate operations involving solutions files with visual studio (devenv.exe) like cleaning solutions,building solutions,etc. it matters the version file, since only the right VS version will be able to read it (without upgrading the file that is) the file.

The solution file is a text file. The file version (which maps one to one to a VS version) is stored on the first line with the following format:

Microsoft Visual Studio Solution File, Format Version XX

whereas XX is the file version format (not the VS internal version mind you).

Visual Studio has an internal version number and an external name (let’s call it the marketing version). The following table has the mapping between the marketing name and the internal version number

Visual Studio 2010 10.0
Visual Studio 2008 9.0
Visual Studio 2005 8.0
Visual Studio .Net 2003 7.1
Visual Studio .Net 2002 7.0


To make things less boring the file version is different from the internal VS version which is different from the marketing version. Smile

For example format version 8.0 corresponds to Visual Studio .Net 2003 (which internally has version 7.1)

The following table contains the marketing version, the internal version number and the file format number for the solution.

Marketing Name Internal Number File Format Number
Visual Studio 2010 10.0 11.00
Visual Studio 2008 9.0 10.00
Visual Studio 2005 8.0 9.00
Visual Studio .Net 2003 7.1 8.00
Visual Studio .Net 2002 7.0 7.00


Starting with Visual Studio 2005 there is also a line saying (under the first line)

# Visual Studio YYYY

where YYYY represents the visual studio version we are accustomed to (2005,2008,…)

So in order to determine a version of a given solution file, we could write a small parser (or a regular expression).

What would be great is if Microsoft provided a parser to cope with all version differences, since parsing a solution file is some work and there is always (a slim) possibility that the file format will change in the future.

Unfortunately Microsoft doesn’t provides us a parser. At least publically. MSBuild ships with an internal parser that we can leverage if we are willing to bend them a little by using reflection. Smile (Note: internal methods are not documented for a reason. If we take this path there is always a risk that this will not work when the next version is released).

The code to get information from a file is quite simple (simple snippet ahead)

Note: This code requires .NET 4.0

using System;

using System.Reflection;
using System.IO;

public enum VisualStudioVersion { VS2010 = 100, VS2008 = 90, VS2005 = 80, VSNet2003 = 71, VSNet2002 = 70, Previous = 0, VSNext = 666 };

public class SolutionHelper

    public static VisualStudioVersion GetSolutionVersion(string solutionFile)
        Type _solutionParser;
        PropertyInfo solutionParser_version;
        PropertyInfo solutionParser_solutionReader;
        MethodInfo solutionParser_parseSolution;

        _solutionParser = Type.GetType("Microsoft.Build.Construction.SolutionParser, Microsoft.Build, version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", false, false);

        if (_solutionParser == null)

            throw new Exception("Can't load msbuild assembly. Is .Net FX 4.0 installed?");

        solutionParser_solutionReader = _solutionParser.GetProperty("SolutionReader", BindingFlags.NonPublic | BindingFlags.Instance);
        solutionParser_version = _solutionParser.GetProperty("version", BindingFlags.NonPublic | BindingFlags.Instance);
        solutionParser_parseSolution = _solutionParser.GetMethod("ParseSolution", BindingFlags.NonPublic | BindingFlags.Instance);
        solutionParser_version = _solutionParser.GetProperty("Version", BindingFlags.NonPublic | BindingFlags.Instance);

        var solutionParserInstance = _solutionParser.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic)[0].Invoke(null);
        using (var streamReader = new StreamReader(solutionFile))
            solutionParser_solutionReader.SetValue(solutionParserInstance, streamReader, null);
            solutionParser_parseSolution.Invoke(solutionParserInstance, null);

        var solutionFileFormatNumber = solutionParser_version.GetValue(solutionParserInstance, null);

        return GetVSVersion(Convert.ToInt32(solutionFileFormatNumber));


    private static VisualStudioVersion GetVSVersion(int version)
        if (version > 11) return VisualStudioVersion.VSNext;

        if (version == 11) return VisualStudioVersion.VS2010;
        if (version == 10) return VisualStudioVersion.VS2008;
        if (version == 9) return VisualStudioVersion.VS2005;
        if (version == 8) return VisualStudioVersion.VSNet2003;
        if (version == 7) return VisualStudioVersion.VSNet2002;

        return VisualStudioVersion.Previous;

This snippet is a little basic. It is not production ready. The final code sample available for download will be a little different, more feature complete and robust.

I will also use this post to slip some news that has gone unnoticed to a lot of people. The next version of Visual Studio (dev11) will allows us to use VS2010 solutions without having to do conversions. This will allow us to do full roundt tripping by using the same solution on VS2010 and Dev11  (I guess I can publically talk about this since Dave Mendlen announced this on this year VSLive at Las Vegas this year)

If this post seems of small value, I hope it’s only a temporary thing, since like the previous one it’s part of a series that will culminate in a post with a very usable scenario in Visual Studio. Stay put (hopefully) in the end all things will make sense Smile

Getting Visual Studio installation directory


Determining the installation path of Visual Studio is something that sometimes is needed. For example we may we need to interact with Visual Studio executable (for example to reset visual studio or registering something on an installer).

But how can we determine where Visual Studio is installed? There are basically two ways of doing it.

  • Getting it from the environment variables.
  • Reading it from the registry

The path is stored in an environment variable called VS<internal version number>COMNTOOLS where <internal version number> is the visual studio internal version number (multiplied by 100). This is not exactly the installation path but we can infer from it.

On my machine I have the following environment variables

VS100COMNTOOLS=C:Program Files (x86)Microsoft Visual Studio 10.0Common7Tools
VS80COMNTOOLS=C:Program Files (x86)Microsoft Visual Studio 8Common7Tools
VS90COMNTOOLS=C:Program Files (x86)Microsoft Visual Studio 9.0Common7Tools

or we can get it from the registry the installation directory which is located on HKLMSOFTWAREMicrosoftVisualStudio<InternalVersionNumber>InstallDir

This is true for 32 bit systems.

On 64 bit systems things are a little bit different. Since Visual Studio doesn’t directly support 64 bit systems, on 64 bit systems VS runs under the Windows on Windows system ( WoW64 ) so we must also that into account on 64 bit systems

in 64 bit systems HKLMSOFTWAREWow6432NodeMicrosoftVisualStudio<InternalVersionNumber>InstallDir

But this only applies on 64 bit processes, if you are running under a 64 bit system but with a 32 bit process you don’t need to get the WoW registry key since windows transparently redirects registry accesses on that case (you can read more about redirection here).

If you follow these rules, you will be fine, but even better then a detailed description would be some running code Smile

This little enumerate allows you to define the several versions in a more friendly way

/// <summary>
/// Represents the several visual studio versions.
/// Internally the value is stored as the VS internal number multiplied by 10 (eg: VS2010 is 100 since it's internal version number is 10.0)
/// </summary>
public enum VisualStudioVersion  { VS2010 = 100, VS2008 = 90 , VS2005 = 80, VSNet2003 = 71, VSNet2002 = 70, Other = 0};

And this code allows us to get the installation directory for the several VS versions

using System;
using Microsoft.Win32;
using System.Globalization;


/// <summary> /// Gets the installation path of a given VS version. /// /// Supported versions 2005, 2008 and 2010, .Net 2003 and .Net 2002 /// </summary> internal static class VisualStudioHelper { /// <summary> /// Gets the installation directory of a given Visual Studio Version /// </summary> /// <param name="version">Visual Studio Version</param> /// <returns>Null if not installed the installation directory otherwise</returns> internal static string GetVisualStudioInstallationDir(VisualStudioVersion version) { string registryKeyString = String.Format(@"SOFTWARE{0}MicrosoftVisualStudio{1}", Environment.Is64BitProcess ? @"Wow6432Node" : "", GetVersionNumber(version)); using (RegistryKey localMachineKey = Registry.LocalMachine.OpenSubKey(registryKeyString)) { return localMachineKey.GetValue("InstallDir") as string; } } /// <summary> /// Gets the version number as used by Visual Studio to identify it's version internally. /// /// eg: Visual Studio 2010 is 10.0 and Visual Studio 2008 is 9.0 /// </summary> /// <param name="version">Visual Studio Version</param> /// <returns>A string with the VS internal number version</returns> private static string GetVersionNumber(VisualStudioVersion version) { if (version == VisualStudioVersion.Other) throw new Exception("Not supported version"); return ((int)version / 10).ToString("{0:0.0}", CultureInfo.InvariantCulture); } }

Executing the following code on a 64 bit operating system





Will result in

C:Program Files (x86)Microsoft Visual Studio 10.0Common7IDE

C:Program Files (x86)Microsoft Visual Studio 9.0Common7IDE

C:Program Files (x86)Microsoft Visual Studio 8Common7IDE


Yes I have all these versions running on my machine (I’ve used to have also VS .NET 2003 but on the last repave I didn’t reinstall it Smile)

Note: This code requires either .Net 3.5 or higher  since it uses  Environment.Is64BitProcess which is only been made available since .Net 3.5 if you want to run this with fwk 2.0 you will need to determine if we are running on a 64 bit process using another method.

Visual Studio internal version numbers are

Visual Studio 2010 10.0
Visual Studio 2008 9.0
Visual Studio 2005 8.0
Visual Studio .Net 2003 7.1
Visual Studio .Net 2002 7.0

Is this useful for something? Perhaps or perhaps not. But that is a history for another post Smile