0

我正在使用此代码将项目添加到代码窗口右键菜单:

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";
}

并且插件设置为自动启动。然而,每次运行 VS2008 时,它都会在菜单中添加另一个按钮,直到我完全删除插件。有谁知道我如何解决这个问题?

例如,我会将 Command.AddControl() 和稍后的内容包装在 if 中,如果仅在按钮不存在时执行,但我似乎找不到在 API 中检查它的方法?

4

3 回答 3

1

我记得在其他地方看到过这个问题,原因是 OnConnection 方法可以出于多种原因多次调用(使用不同的 connectMode 值),因此存在一些技巧(或特殊性,取决于您如何看待它以及如何你知道的大部分)都涉及。

但是,我不是这个主题的专家,所以这里有一些链接可以帮助你:

HOWTO:正确使用 Visual Studio 加载项的 OnConnection 方法

HOWTO:从加载项向 Visual Studio .NET 添加按钮、命令栏和工具栏

HOWTO:控制 Visual Studio 加载项中的命令状态

这些有点太长了,无法在这里总结(至少在我看来是这样),但它们确实有你需要的信息。

另外,这里是关于编写 VS 插件的文章列表,可能会很有帮助: http ://www.mztools.com/resources_vsnet_addins.aspx

HTH。


编辑:我想,Money J 的回答更中肯,基本上是对您需要做的事情的非常简短的总结,如果这就是您所追求的 - 太好了。但是,我相信我提供链接的页面上包含的信息非常有用,因此您可能也想阅读这些信息。

于 2009-09-19T00:09:37.693 回答
0

我以前没有为 VS.NET 2008 编写过插件,但是看看你的方法有什么可用的:

检查 ext_cm_UISetup?

 if(connectMode == ext_ConnectMode.ext_cm_UISetup)
    {

此外,在您的尝试块中,您应该能够使用资源管理器...

 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);

还有一张方便的图表,将来可能会有所帮助。

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

于 2009-09-19T00:12:00.760 回答
0

尝试改变:

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

...到:

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

...并将整个内容包装在:

#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
}
于 2009-09-19T03:02:26.627 回答