HOWTO: Get supported frameworks and profiles of a Visual Studio version from a package

Author: Carlos J. Quintero (Microsoft MVP) Applies to: Microsoft Visual Studio 2010
Date: April 2015   Microsoft Visual Studio 2012
      Microsoft Visual Studio 2013
      Microsoft Visual Studio 2015

While Visual Studio 2005 can target only .NET Framework 2.0, which uses the Common Language Runtime (CLR) 2.0, Visual Studio 2008 can target more than one .NET Framework: 2.0, 3.0 or 3.5 (although they all use CLR 2.0). Visual Studio 2008 also introduced .NET Framework profiles (such as the Client Profile), which are subsets of the .NET Framework. Visual Studio 2010 introduced the possibility of targeting .NET Framework versions using different CLR versions (2.0 and 4.0).

This capability is called framework multi-targeting. The combination of a .NET Framework, version and profile is named .NET Framework moniker. This article explains how to get the supported .NET Frameworks, versions and profiles, that is, .NET Framework monikers (and friendly names), from a Visual Studio package.

More Information

The .NET Framework moniker used by a given project can be retrieved using the IVsHierarchy.GetProperty method with the __VSHPROPID4.VSHPROPID_TargetFrameworkMoniker property (introduced by Visual Studio 2010).

The information about framework multi-targeting is provided by the IVsFrameworkMultiTargeting interface (also only available for Visual Studio 2010 and higher), which provides methods to enumerate supported .NET Frameworks monikers, to get the display name of a moniker, get the assemblies of a .NET Framework moniker, etc.

As an example, the following package creates a menu command that, when clicked, shows each supported moniker (.NET Framework, version and profile) and display name:

Language: C#   Copy Code Copy Code (IE only)
using System;
using System.Runtime.InteropServices;
using System.ComponentModel.Design;
using Microsoft.Win32;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Shell;

namespace MyCompany.VSPackageTargetFrameworks
   [PackageRegistration(UseManagedResourcesOnly = true)]
   [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
   [ProvideMenuResource("Menus.ctmenu", 1)]
   public sealed class VSPackageTargetFrameworksPackage : Package
      public VSPackageTargetFrameworksPackage()

      protected override void Initialize()

         OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
         if (null != mcs)
            CommandID menuCommandID = new CommandID(GuidList.guidVSPackageTargetFrameworksCmdSet,
            MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID);

      private void MenuItemCallback(object sender, EventArgs e)
         IVsFrameworkMultiTargeting frameworkMultiTargeting;
         Array supportedFrameworkMonikers = null;
         string supportedFrameworkDisplayName;
         string msg;

         frameworkMultiTargeting = base.GetService(typeof(SVsFrameworkMultiTargeting)) 
            as IVsFrameworkMultiTargeting;

         frameworkMultiTargeting.GetSupportedFrameworks(out supportedFrameworkMonikers);

         if (supportedFrameworkMonikers != null)
            foreach (string supportedFrameworkMoniker in supportedFrameworkMonikers)
                  out supportedFrameworkDisplayName);

               msg = "Moniker: " + supportedFrameworkMoniker + "\r\n";
               msg += "Display Name: " + supportedFrameworkDisplayName;



Go to the 'Visual Studio Extensibility (VSX)' web site for more articles like this (Articles section)