ewanm89
ewanm89

Reputation: 929

VS2008 Addin add to menu

I'm using this code to add an item to the code window right click menu:

public void OnConnection(
 object application, 
 ext_ConnectMode connectMode, 
 object addInInst, 
 ref Array custom)
{
    _applicationObject = (DTE2)application;
    _addInInstance = (AddIn)addInInst;

    object[] contextGUIDS = new object[] { };
    Command codeWindowCommand = null;
    CommandBarControl codeWindowButton;
    CommandBar codeCommandBar;
    CommandBars commandBars;

    try
    {
        codeWindowCommand = _applicationObject.Commands.Item(
            _addInInstance.ProgID + "." + CODEWINDOW_COMMAND_NAME, 0);
    }
    catch
    {
    }

    if (codeWindowCommand == null)
    {
        codeWindowCommand = _applicationObject.Commands.AddNamedCommand(
            _addInInstance, 
            CODEWINDOW_COMMAND_NAME, 
            CODEWINDOW_COMMAND_NAME, 
            "Pastebin selected code", 
            true, 
            18, 
            ref contextGUIDS, 
            (int)vsCommandStatus.vsCommandStatusSupported + 
            (int)vsCommandStatus.vsCommandStatusEnabled);
    }

    commandBars = (CommandBars)_applicationObject.CommandBars;

    codeCommandBar = commandBars["Code Window"];

    codeWindowButton = (CommandBarControl)codeWindowCommand.AddControl(
        codeCommandBar, codeCommandBar.Controls.Count + 1);
    codeWindowButton.Caption = "Text for button";
    codeWindowButton.TooltipText = "Tooltip for button";
}

and the addin is set to autostart. However each time the run VS2008 it adds another button to the menu until I totally delete the addin. Anyone know how I fix this?

I would for example wrap the Command.AddControl() and later stuff in an if that only executes if the button doesn't already exist, but I can't seem to find a way to check this in the API?

Upvotes: 0

Views: 1152

Answers (3)

KristoferA
KristoferA

Reputation: 12397

Try changing:

codeWindowCommand = _applicationObject.Commands.Item(_addInInstance.ProgID + "." + CODEWINDOW_COMMAND_NAME, 0); 

...to:

codeWindowCommand = _applicationObject.Commands.Item(_addInInstance.ProgID + "." + CODEWINDOW_COMMAND_NAME, -1); 

...and wrap the whole thing in:

#if DEBUG
if (connectMode == ext_ConnectMode.ext_cm_UISetup)
#else
if (connectMode == ext_ConnectMode.ext_cm_Startup || connectMode == ext_ConnectMode.ext_cm_AfterStartup)
#endif
{
    //add-in startup code goes here
}

Upvotes: 0

AASoft
AASoft

Reputation: 1344

I remember seeing this problem elsewhere, and the reason was that the OnConnection method can be called at multiple times for multiple reasons (with different values of connectMode), so there is some trickery (or peculiarities, depending on how you look at it and how much of this you know) involved.

However, I am not an expert on this topic, so here are some links that will help you:

HOWTO: Use correctly the OnConnection method of a Visual Studio add-in

HOWTO: Adding buttons, commandbars and toolbars to Visual Studio .NET from an add-in

HOWTO: Controlling the state of command in a Visual Studio add-in

Those are somewhat too long to just summarize here (at least it seems like that to me), but they do have the information you need.

Also, here is a list of articles on writing VS addins, which will probably be very helpful: http://www.mztools.com/resources_vsnet_addins.aspx

HTH.


EDIT: Money J's answer is a bit more to the point, I suppose, and is basically a very short summary of what you need to do, and if that's all you're after - great. However, I believe that the information contained on the pages I provided the links to is very useful, so you might want to read that as well.

Upvotes: 1

Money J
Money J

Reputation:

I haven't written an addin for VS.NET 2008 before, but seeing what you have available on your method:

Check for ext_cm_UISetup?

 if(connectMode == ext_ConnectMode.ext_cm_UISetup)
    {

also, in your try block you should be able to use the resourcemanager...

 ResourceManager resourceManager = new     
          ResourceManager("MyAddin1.CommandBar",  
          Assembly.GetExecutingAssembly());
        CultureInfo cultureInfo = new 
          System.Globalization.CultureInfo
          (_applicationObject.LocaleID);
        string resourceName = String.Concat(cultureInfo.
          TwoLetterISOLanguageName, "Tools");
        toolsMenuName = resourceManager.GetString(resourceName);

And a handy diagram that might help in the future.

http://msdn.microsoft.com/en-us/library/za2b25t3.aspx

Upvotes: 0

Related Questions