BUG: Command.Bindings causes Exception when setting value from an add-in in localized Visual Studio.

Author: Carlos J. Quintero (Microsoft MVP) Applies to: Microsoft Visual Studio 2005
Date: September 2012   Microsoft Visual Studio 2008
      Microsoft Visual Studio 2010
      Microsoft Visual Studio 2012

This article explains a bug in the EnvDTE.Command.Bindings property with modifiers keys (Alt, Shift, Ctrl) in localized versions of Visual Studio.

More information

In localized versions of Visual Studio, the EnvDTE.Command.Bindings property returns modifiers keys localized, for example, "Éditeur de texte::Ctrl+Maj+Alt+F" in French. However, when assigning that same value to the property, it causes System.ArgumentException. To succeed, the modifiers must be in English: "Éditeur de texte::Ctrl+Shift+Alt+F".

Note: the the scope ("Éditeur de texte") must be always in French.

This bug poses a problem in localized versions of Visual Studio if an add-in needs to re-create a command for whatever reason and wants to preserve the existing command binding.

The following addin reproduces the problem in French versions of Visual Studio.

Language: VB.NET   Copy Code Copy Code (IE only)
Imports System
Imports Microsoft.VisualStudio.CommandBars
Imports Extensibility
Imports EnvDTE
Imports EnvDTE80

Public Class Connect
   Implements IDTExtensibility2

   Private Const COMMAND_NAME As String = "MyCommand"

   Private _applicationObject As DTE2
   Private _addInInstance As AddIn

   Public Sub OnConnection(ByVal application As Object, ByVal connectMode As ext_ConnectMode, ByVal addInInst As Object, _
      ByRef custom As Array) Implements IDTExtensibility2.OnConnection

      Dim cmd As Command = Nothing
      Dim bindings As Object

      _applicationObject = CType(application, DTE2)
      _addInInstance = CType(addInInst, AddIn)


         Select Case connectMode

            Case ext_ConnectMode.ext_cm_AfterStartup, ext_ConnectMode.ext_cm_Startup

                  cmd = _applicationObject.Commands.Item(_addInInstance.ProgID & "." & COMMAND_NAME)

                  If Not cmd Is Nothing Then
                  End If

               Catch ex As Exception
               End Try

               cmd = _applicationObject.Commands.AddNamedCommand(_addInInstance, COMMAND_NAME, "My command", "My tooltip", True, 59)

               ' Assign the binding with modifiers in English. It succeeds
               cmd.Bindings = New Object() {"Éditeur de texte::Ctrl+Shift+Alt+F"}

               ' Get the binding. It returns "Éditeur de texte::Ctrl+Maj+Alt+F"
               bindings = cmd.Bindings

               MessageBox.Show(CType(bindings, Object())(0).ToString)

               ' Reassign the bindings with modifiers in French. It causes System.ArgumentException.
               cmd.Bindings = bindings

         End Select

      Catch ex As Exception


      End Try

   End Sub

   Public Sub OnDisconnection(ByVal disconnectMode As ext_DisconnectMode, ByRef custom As Array) _
      Implements IDTExtensibility2.OnDisconnection
   End Sub

   Public Sub OnAddInsUpdate(ByRef custom As Array) Implements IDTExtensibility2.OnAddInsUpdate
   End Sub

   Public Sub OnStartupComplete(ByRef custom As Array) Implements IDTExtensibility2.OnStartupComplete
   End Sub

   Public Sub OnBeginShutdown(ByRef custom As Array) Implements IDTExtensibility2.OnBeginShutdown
   End Sub

End Class

Go back to the 'Resources for Visual Studio .NET extensibility' section for more articles like this