public static Command CreateCommandButton(this Commands2 me, AddIn addin, CommandBase command) { object[] contextGUIDS = new object[] { }; Commands2 commands = me; // Try to retrieve the command. If it was created already, just leave since the command exists. Command vsCommand = me.GetCommand(me.GetFullname(addin, command.Name)); if (vsCommand != null) { return(null); // it already exists } try { // Try to create a command with icon. // This usually fails using Visual Studio 2005 if the VsTortoise satellite dll culture does not match the one of Visual Studio. vsCommand = commands.AddNamedCommand2(addin, command.Name, command.Caption, command.Tooltip, false, Type.Missing, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton); } catch { } if (vsCommand == null) { // We're here when command creation failed, so create it without icon. vsCommand = commands.AddNamedCommand2(addin, command.Name, command.Caption, command.Tooltip, true, (int)0, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton); } if (vsCommand != null) { // First check if there is a preferred binding at all, // to skip unnecessary further expensive tests if (!string.IsNullOrEmpty(command.PreferredBinding)) { // The command inside VS has been added. // Now check if any command is using the preferred binding already. // We use it only, when it is not used by another command! // Bindings are "atomic". If we would use a binding that is in use already, // the binding gets removed from the current command. We don't want to steal bindings from other commands! bool bindingUsedAlready = me.GetCommandByBinding(command.PreferredBinding) != null; if (!bindingUsedAlready) { try { // TODO: figure how to assign bindings correctly // Bindings use translated texts, this is so ridiculous. // I don't know how to assign a shortcut in a language independent way, // so we use a try/catch here, otherwise the add-in refuses to start-up. // English: "Text Editor::Ctrl+Shift+Alt+Up Arrow" // German.: "Text-Editor::Strg+Umschalt+Alt+NACH-OBEN-TASTE" vsCommand.Bindings = command.PreferredBinding; } catch { } } } } return(vsCommand); }