A wrong way of checking the Visual Studio version where an add-in is loaded

Take a look at this code of an add-in that checks that it is loaded only in Visual Studio 2012 and try to figure out what’s wrong:

private DTE2 _applicationObject;
private AddIn _addInInstance;

public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
{
   const string REGISTRY_KEY_VS_11_0 = "SOFTWARE\MICROSOFT\VISUALSTUDIO\11.0";

   string addInRegistryRoot = null;

   _applicationObject = (DTE2)application;
   _addInInstance = (AddIn)addInInst;

   switch (connectMode)
   {
      case ext_ConnectMode.ext_cm_AfterStartup:
      case ext_ConnectMode.ext_cm_Startup:

         addInRegistryRoot = _applicationObject.RegistryRoot.ToUpper();

         if (!addInRegistryRoot.StartsWith(REGISTRY_KEY_VS_11_0))
         {
            System.Windows.Forms.MessageBox.Show("This add-in only works with Visual Studio 2012");
         }
         break;
   }
}

If you have discovered it, either you are quite expert on globalization issues or you are a Turkish developer. My MZ-Tools add-in had similar code that has worked correctly for years until a few weeks ago, when a developer reported that using the Turkish culture (user interface, language input keyboard, etc.) MZ-Tools refused to load. You can simulate that effect inserting the following line at the start the OnConnection method that sets the Turkish culture for the current thread:

System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo(“tr-TR”);

The reason is that in Turkish, the upper case of the character i is not I but İ (with a dot), as explained here. So _applicationObject.RegistryRoot.ToUpper() returns the following string:

“SOFTWARE\MİCROSOFT\VİSUALSTUDİO\11.0”

which is different from:

“SOFTWARE\MICROSOFT\VISUALSTUDIO\11.0”

Of course, the solution is to use _applicationObject.RegistryRoot.ToUpperInvariant() or an overloaded version of StartsWith() that uses the ordinal or invariant culture comparison ignoring the case.

So, if you make software for international markets, ensure that you run the Code Analysis feature of Visual Studio with the Microsoft Globalization Rules, because two rules are violated with the code above:

– CA1304: Specify CultureInfo (in _applicationObject.RegistryRoot.ToUpper())
– CA1307: Specify StringComparison (in sAddInRegistryRoot.StartsWith(REGISTRY_KEY_VS_11_0))

3 thoughts on “A wrong way of checking the Visual Studio version where an add-in is loaded”

  1. Maybe I’m missing something, but why would one go through that trouble, when you can just check DTE.Version?

  2. I was using that approach because MZ-Tools 6.0 was also an add-in for the Macros IDE and I needed to know not only the IDE version but the IDE kind (Visual Studio or Macros IDE).

    The registry roots could be used for that purpose because they are of the form SoftwareMicrosoftVSA or SoftwareMicrosoftVisualStudio

  3. These are the steps that I thought geratened a reproducible case of this problem. I’ll take a look this week and see if there’s something I left out.Create and build a new Editor Classifier project.In the Fonts and Colors dialog of the Exp instance, locate the Ordinary Text display item. Change both foreground and background to something memorable and very different than the defaults. Open a solution and confirm the colors work as expected.Make sure IDE startup option is set to show empty environment. Close the IDE.Start IDE and do not load a solution or any files.Open Font and Colors option page, confirm previous non-default color selection still appears in Ordinary Text. IMPORTANT: do NOT press OK. Instead, press cancel.Load solution and see that text is rendered using default rather than user selected colors.Open F & C dialog and press OK without making any changes at all to fix the colors used in the editor.

Comments are closed.