【问题标题】:Visual Studio 2010 Plug-in - Adding a context-menu to the Solution ExplorerVisual Studio 2010 插件 - 将上下文菜单添加到解决方案资源管理器
【发布时间】:2011-03-02 07:37:09
【问题描述】:

我想在 Visual Studio 2010 的解决方案资源管理器的上下文菜单中为特定文件类型添加一个新选项。例如,右键单击 *.cs 文件将显示现有的上下文菜单以及“我的新选项”。

我想知道代码会是什么样子;并且希望获得一个指向开发 Visual Studio 插件的良好参考的指针。我看到的教程/参考资料非常可怕。

谢谢!

【问题讨论】:

    标签: c# visual-studio-2010 visual-studio plugins


    【解决方案1】:

    我花了大约 5 个小时才完成这项工作。

    有 2 个选项,Visual Studio 插件(或共享插件) vs Visual Studio 包。

    这个包要复杂得多,可以让你有更多的控制权,但对于解决方案资源管理器上的上下文菜单,它不是必需的。

    新项目-> 其他项目类型-> 可扩展性-> Visual Studio 插件。

    这是一个演练 - Link

    还有这个我关注了一些 - Link

    我建议您保留添加到工具菜单的选项,直到上下文菜单正常工作,或者提供放置设置对话框的位置(如果您不编写工具-> 选项页面。

    这是连接代码:

      _applicationObject = (DTE2)application;
            _addInInstance = (AddIn)addInInst;
            if (connectMode == ext_ConnectMode.ext_cm_UISetup)
            {
                object[] contextGUIDS = new object[] { };
                Commands2 commands = (Commands2)_applicationObject.Commands;
                string toolsMenuName = "Tools";
    
                //Place the command on the tools menu.
                //Find the MenuBar command bar, which is the top-level command bar holding all the main menu items:
                Microsoft.VisualStudio.CommandBars.CommandBar menuBarCommandBar = ((Microsoft.VisualStudio.CommandBars.CommandBars)_applicationObject.CommandBars)["MenuBar"];
    
                //Find the Tools command bar on the MenuBar command bar:
                CommandBarControl toolsControl = menuBarCommandBar.Controls[toolsMenuName];
                CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl;
                // get popUp command bars where commands will be registered.
                CommandBars cmdBars = (CommandBars)(_applicationObject.CommandBars);
                CommandBar vsBarItem = cmdBars["Item"]; //the pop up for clicking a project Item
                CommandBar vsBarWebItem = cmdBars["Web Item"];
                CommandBar vsBarMultiItem = cmdBars["Cross Project Multi Item"];
                CommandBar vsBarFolder = cmdBars["Folder"];
                CommandBar vsBarWebFolder = cmdBars["Web Folder"];
                CommandBar vsBarProject = cmdBars["Project"]; //the popUpMenu for right clicking a project
                CommandBar vsBarProjectNode = cmdBars["Project Node"];
    
                //This try/catch block can be duplicated if you wish to add multiple commands to be handled by your Add-in,
                //  just make sure you also update the QueryStatus/Exec method to include the new command names.
                try
                {
                    //Add a command to the Commands collection:
                    Command command = commands.AddNamedCommand2(_addInInstance, "HintPaths", "HintPaths", "Executes the command for HintPaths", true, 59, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton);
    
                    //Add a control for the command to the tools menu:
                    if ((command != null) && (toolsPopup != null))
                    {
                        //command.AddControl(toolsPopup.CommandBar, 1);
                        command.AddControl(vsBarProject); 
                    }
                }
                catch (System.ArgumentException argEx)
                {
                    System.Diagnostics.Debug.Write("Exception in HintPaths:" + argEx.ToString());
                    //If we are here, then the exception is probably because a command with that name
                    //  already exists. If so there is no need to recreate the command and we can 
                    //  safely ignore the exception.
                }
            }
        }
    

    此代码检查用户选择的项目是否为例如项目:

      private Project GetProject()
        {
            if (_applicationObject.Solution == null || _applicationObject.Solution.Projects == null || _applicationObject.Solution.Projects.Count < 1)
                return null;
            if (_applicationObject.SelectedItems.Count == 1 && _applicationObject.SelectedItems.Item(1).Project != null)
                return _applicationObject.SelectedItems.Item(1).Project;
            return null;
        }
    

    请注意,您的代码中的某些字符串名称必须匹配,我不确定它们是哪一个,因为我昨天刚刚这样做了。

    【讨论】:

    【解决方案2】:

    我发现最好的方法是制作 Visual Studio 包而不是 Visual Studio 插件。 vsix 部署体验非常流畅 - 整个过程非常简单。它只支持 Visual Studio 2010,但对我来说已经足够了。

    这是生成的 vsct:

    <Commands package="guidBingfooPluginPkg">
        <Groups>
          <Group guid="guidBingfooPluginCmdSet" id="MyMenuGroup" priority="0x0600">
            <Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_ITEMNODE"/>
          </Group>
        </Groups>
    
        <Buttons>
          <Button guid="guidBingfooPluginCmdSet" id="cmdidfooLocalBox" priority="0x0100" type="Button">
            <Parent guid="guidBingfooPluginCmdSet" id="MyMenuGroup" />
            <!-- <Icon guid="guidImages" id="bmpPic1" /> -->
            <CommandFlag>DynamicVisibility</CommandFlag>
            <Strings>
              <CommandName>cmdidfooLocalBox</CommandName>
              <ButtonText>View in foo</ButtonText>
            </Strings>
          </Button>
    
          <Button guid="guidBingfooPluginCmdSet" id="cmdidfooTestBed" priority="0x0100" type="Button">
            <Parent guid="guidBingfooPluginCmdSet" id="MyMenuGroup" />
            <CommandFlag>DynamicVisibility</CommandFlag>
            <Strings>
              <CommandName>cmdidfooTestBed</CommandName>
              <ButtonText>View in foo on Test Beds</ButtonText>
            </Strings>
          </Button>
    
        </Buttons>
    
        <Bitmaps>
          <Bitmap guid="guidImages" href="Resources\Images_32bit.bmp" usedList="bmpPic1, bmpPic2, bmpPicSearch, bmpPicX, bmpPicArrows"/>
        </Bitmaps>
      </Commands>
    
      <Symbols>
        <GuidSymbol name="guidBingfooPluginPkg" value="{62c4a13c-cc61-44a0-9e47-33111bd323ce}" />
    
        <GuidSymbol name="guidBingfooPluginCmdSet" value="{59166210-d88c-4259-9809-418bc332b0ab}">
          <IDSymbol name="MyMenuGroup" value="0x1020" />
          <IDSymbol name="cmdidfooLocalBox" value="0x0100" />
          <IDSymbol name="cmdidfooTestBed" value="0x0101" />
        </GuidSymbol>
    
        <GuidSymbol name="guidImages" value="{2dff8307-a49a-4951-a236-82e047385960}" >
          <IDSymbol name="bmpPic1" value="1" />
          <IDSymbol name="bmpPic2" value="2" />
          <IDSymbol name="bmpPicSearch" value="3" />
          <IDSymbol name="bmpPicX" value="4" />
          <IDSymbol name="bmpPicArrows" value="5" />
        </GuidSymbol>
      </Symbols>
    </CommandTable>
    

    【讨论】:

    • 谢谢,这很有帮助;你是如何处理菜单项的 DynamicVisibility 的?
    【解决方案3】:

    更新:

    VS2010 的 GAX/GAT 也可从http://msdn.microsoft.com/en-us/library/ff687173 获得

    原帖

    这很可怕,因为 VS 真的很复杂。可以使用 GAX/GAT,但有 no VS2010 Version yet。 我的建议是从Visual Studio Gallery 下载一些示例,以尝试了解整个事情的工作原理,遗憾的是这不是一件容易的事。

    HTH

    【讨论】:

    • +1 这确实不是一个坏主意,尤其是对于更复杂的东西。不过,我建议您在学习了基础知识后再执行此操作。
    【解决方案4】:

    我发现自己必须在代码编辑器窗口上下文菜单中添加一个项目,最终结果是 cmdBars["Script Context"],因为我希望它专门用于 JavaScript 文件。

    作为一种我觉得很有用的发现技巧,我通过以下循环将新菜单项添加到 Visual Studio 中的所有 (456) 菜单控件中:

    foreach (CommandBar cc in cmdBars)
    {
        if (cc.Index >= 1 && cc.Index <= 456)
        {
            command.AddControl(cmdBars[cc.NameLocal]);
        }
    }
    

    然后我通过调整循环的边界使用分而治之的技术来缩小范围:

        if (cc.Index >= 1 && cc.Index <= 256)
        ...
        if (cc.Index >= 1 && cc.Index <= 128)
        ...
        if (cc.Index >= 64 && cc.Index <= 128)
        ...etc...
    

    直到我最终找到了我想要的东西。

    (与此相关的问题在Visual Studio 2010 Plug-in - Adding a context-menu to the Editor Window

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-15
      • 2012-08-31
      • 1970-01-01
      • 2011-03-27
      • 1970-01-01
      相关资源
      最近更新 更多