Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VSIX: Adding a Menu Item to the Visual Studio Editor Context Menu

I have an internal extension I'd like to add to Visual Studio that should hook up to the Editor Context menu - regardless of what type of file is open. I can handle enabling/visibility dynamically but essentially I'd like it to be accessible on any type of editor file.

I've not been able to find the right parent command/group ids to manage to get a custom button to display on the editor context menu. I suspect there's not a single Id but several but any guidance on what I should be looking at. Having a hard time figuring out what the proper parent command Id is to hook up to the editor context menu.

Specifically I need to be able to add View in Browser option to files that Visual Studio doesn't recognize as HTML/Web files (even though they are mapped to the appropriate editors).

Related: Is there anyway to reasonable way to discover the menu command and group names? Poking around in the SharedCommandPlace.vsct is as close as I've come but even that is proving to be very difficult to match to actual menu items.

like image 711
Rick Strahl Avatar asked Aug 01 '15 07:08

Rick Strahl


People also ask

How to Add menu item Visual Studio?

In the Solution Explorer, right-click the project node and select Add > New Item. In the Add New Item dialog, go to Visual C# / Extensibility and select Command.

How do I create a VSIX file in Visual Studio?

Create a new VSIX project in Visual Studio 2019 through File->New->Project. Search for VSIX Project and click Next. Set the project name to SampleExtension and click Create. The new VSIX project is now created with asynchronous service.

Where is the context menu in Visual Studio?

Menu items appear in views, actions, and right-click menus.


2 Answers

I needed the same thing and I used:

<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_CODEWIN"/>

So, I just changed the id. See: https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.shell.vsmenus.idm_vs_ctxt_codewin.aspx

like image 87
Mihai Mahulea Avatar answered Oct 04 '22 19:10

Mihai Mahulea


I was able to figure out the right command groups for the context menu. It turns out the various editors all use separate context ids and so have to be managed as separate menus so this gets messy quick.

Steps

  1. I used the HKEY_CURRENT_USER\SOFTWARE\Microsoft\VisualStudio\14.0\General key and EnableVSIPLogging value of 1 to enable logging.
  2. I then navigated into the editor and with the mouse on an empty area press CTRL-SHIFT and then right click the mouse

This gives the info a menu group like and it looks like this:

---------------------------
VSDebug Message
---------------------------
Menu data:
    Guid = {D7E8C5E1-BDB8-11D0-9C88-0000F8040A53}
    GuidID = 358
    CmdID = 53
    Type = 0x00000400
    Flags = 0x00000000
    NameLoc = ASPX Context
---------------------------
OK   
---------------------------

The important values are the GUID and the CommandID.

Add the Guid and Command ID under Symbols like this to register the command set mapping the Guid to the CommandSet and the CommandId to the context menu values:

<GuidSymbol name="aspxContextCommandSet" value="{D7E8C5E1-BDB8-11D0-9C88-0000F8040A53}">
  <IDSymbol name="aspxContextMenu" value="0x0035"/>
</GuidSymbol>

Note that the value maps to the CommandID represented as a hex value.

Then reference this group as a parent for your command group (MyMenuGroup) in the Groups section:

<Group guid="guidViewInBrowserPackageCmdSet" id="MyMenuGroup" priority="0x0000">
  <Parent guid="aspxContextCommandSet" id="aspxContextMenu"/>
</Group>

You reference the menu group you create for you command buttons and point at the context menu created in the previous step.

If you want to do this for multiple editors (ie. the ASPX, HTML, and Code editors for example as I do) you repeat this process for each of your editors by adding both the GuidSymbol and the Group.You'll end up with multiple Group entries for the same MenuGroup point at a different parent and all will activate appropriately.

Works great, but you'll probably have to make sure you filter your OleMenuCommand objects with a BeforeQueryStatus event handler to ensure the menu shows only when you actually can handle.

like image 27
Rick Strahl Avatar answered Oct 04 '22 19:10

Rick Strahl