代码之家  ›  专栏  ›  技术社区  ›  Kenn Zelleriation

Visual Studio 2010插件-向解决方案资源管理器添加上下文菜单

  •  46
  • Kenn Zelleriation  · 技术社区  · 14 年前

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

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

    谢谢!

    4 回复  |  直到 11 年前
        1
  •  32
  •   Zuuum    12 年前

    我花了大约5个小时才这么做。

    有两个选项,Visual Studio加载项(或共享加载项)与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
  •  16
  •   Kenn Zelleriation    14 年前

    我发现最好的方法是制作一个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>
    
        3
  •  3
  •   Zuuum    12 年前

    更新:

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

    原帖

    嗯,很可怕,因为vs是非常复杂的。使用GAX/GAT是可能的,但是 no VS2010 Version yet . 我建议从 Visual Studio Gallery 试着理解整个事情是如何运作的,可惜这不是一件容易的事情。

    高温高压

        4
  •  2
  •   Community basarat    7 年前

    我发现自己不得不在代码编辑器窗口上下文菜单中添加一个项目,结果是 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 )