Detecting The Installed Languages For Visual Studio 2010 And 2012
Recently I needed to detect the installed languages for Visual Studio 2010 and 2012 along with the primary language (the language of the installer). There’s some information on how to do this on the MSDN site but there’s no official code to do it for you, not from outside Visual Studio at least.
The way to detect the installed languages requires that you know what edition is installed. The only way to find that out is to check the registry keys for each edition until one of them is found. There are three editions of Visual Studio plus the integrated/shell version which is what programs such as SQL Management Studio are built on.
The basic process to get this information requires looking at the available keys under HKLM\Software\Microsoft\DevDiv\vs\Servicing\11.0
.
Among these keys will be one for the edition (Professional, Premium, Ultimate, or Integrated/Shell) and then beneath that will be a key with the Locale ID.
The process differs a bit between versions though.
For Visual Studio 2010 there will only be one Locale ID which is the language of the installer.
Language packs are listed under another key which is HKLM\Software\Microsoft\DevDiv\vs\Servicing\10.0\prolp
.
But for Visual Studio 2012 all languages are listed under the edition key.
This means there’s no way to detect what the primary language is so we simply make an educated guess and look at the HKCU\Software\Microsoft\VisualStudio\11.0\General
key.
Under here will be an entry called UILanguage
whose value will be the user’s selected language (this is the value located under Tools > Options > International Settings).
Putting It All Together
To make these checks easier to use I wrote up two classes that will detect what edition is installed along with what languages are available to the user.
Currently the Integrated/Shell check for Visual Studio 2012 is missing since the key name isn’t listed on the MSDN site.
So instead of taking a guess (I think it’s devenv
or minshellcore
) I left this check out.
If anyone knows the correct key let me know and I’ll update the code with it.
All checks against the HKLM\Software
hive need to check if the system is 64bit or not.
For that there’s a method called GetSoftwareRoot()
which handles the check for us.
public static class VisualStudio2010{ // http://stackoverflow.com/q/1074411/39605 private static RegistryKey GetSoftwareRoot() { var path = IntPtr.Size == 8 ? @"Software\Wow6432Node" : @"Software"; return Registry.LocalMachine.OpenSubKey(path); }
// http://blogs.msdn.com/b/heaths/archive/2010/05/04/detection-keys-for-net-framework-4-0-and-visual-studio-2010.aspx public enum Edition { Undefined = -1, IntShell = 0, PROCore = 1, VSTDCore = 2, VSTSCore = 3 }
public static Edition InstalledEdition() { var rootKey = GetSoftwareRoot().OpenSubKey(@"Microsoft\DevDiv\VS\Servicing\10.0"); if (rootKey == null) { return Edition.Undefined; }
var subkeys = rootKey.GetSubKeyNames() .OrderByDescending(x => x, StringComparer.OrdinalIgnoreCase);
var names = Enum.GetNames(typeof(Edition)); Array.Reverse(names); // this makes IntShell the last value checked
foreach (var name in names) { if (subkeys.Contains(name, StringComparer.OrdinalIgnoreCase)) { return (Edition) Enum.Parse(typeof (Edition), name); } }
return Edition.Undefined; }
public static bool IsVersionInstalled(Edition edition) { try { var key = GetSoftwareRoot().OpenSubKey(@"Microsoft\DevDiv\VS\Servicing\10.0").OpenSubKey(edition); return key != null; } catch { return false; } }
public static string PrimaryLanguage(Edition edition) { try { var rootKey = GetSoftwareRoot().OpenSubKey(@"Microsoft\DevDiv\VS\Servicing\10.0").OpenSubKey(edition); if (rootKey == null) { return null; }
var keys = rootKey.GetSubKeyNames(); if (keys.Length > 1) { throw new Exception("There are multiple sub keys. Unable to determine the primary language."); }
return keys[0]; } catch { return null; } }
public static string[] AllLanguages(Edition edition) { var languages = new[] { PrimaryLanguage(edition) };
var languagePacks = GetSoftwareRoot().OpenSubKey(@"Microsoft\DevDiv\VS\Servicing\10.0\prolp"); if (languagePacks != null && languagePacks.SubKeyCount != 0) { languages = languages.Concat(languagePacks.GetSubKeyNames()).ToArray(); }
return languages; }}
public static class VisualStudio2012{ // http://stackoverflow.com/q/1074411/39605 private static RegistryKey GetSoftwareRoot() { var path = IntPtr.Size == 8 ? @"Software\Wow6432Node" : @"Software"; return Registry.LocalMachine.OpenSubKey(path); }
// http://technet.microsoft.com/en-us/library/ee225238(v=vs.110).aspx public enum Edition { Undefined = -1, Professional = 1, Premium = 2, Ultimate = 3 }
public static Edition InstalledEdition() { var rootKey = GetSoftwareRoot().OpenSubKey(@"Microsoft\DevDiv\vs\Servicing\11.0"); if (rootKey == null) { return Edition.Undefined; }
var subkeys = rootKey.GetSubKeyNames() .OrderByDescending(x => x, StringComparer.OrdinalIgnoreCase);
var names = Enum.GetNames(typeof(Edition));
foreach (var name in names) { if (subkeys.Contains(name, StringComparer.OrdinalIgnoreCase)) { return (Edition) Enum.Parse(typeof(Edition), name); } }
return Edition.Undefined; }
public static bool IsVersionInstalled(Edition edition) { try { var key = GetSoftwareRoot().OpenSubKey(@"Microsoft\DevDiv\VS\Servicing\11.0").OpenSubKey(edition); return key != null; } catch { return false; } }
public static string PrimaryLanguage() { try { var rootKey = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\VisualStudio\11.0\General"); if (rootKey == null) { return null; }
var language = (int) rootKey.GetValue("UILanguage", 0); if (language == 0) { throw new Exception("Unable to determine the primary language."); }
return language.ToString(CultureInfo.InvariantCulture); } catch { return null; } }
public static string[] AllLanguages(Edition edition) { var rootKey = GetSoftwareRoot().OpenSubKey(@"Microsoft\DevDiv\vs\Servicing\11.0").OpenSubKey(edition); if (rootKey == null) { throw new Exception("Unable to find registry key for the " + edition + " edition."); }
return rootKey.GetSubKeyNames(); }}