Search code examples
c#.netvisual-studio-extensionsvsixvsct

Visual Studio Extension - Can't put my button in ProjectNode/Add/ submenu


Context

Hi there, I am developing a VS Extension, it is just a button which opens a view where you can configure the creation of a custom Azure Function which actually includes Folders, subfolders, classes which inherit from custom classes, etc..

Problem

I am not being able to locate my button in the desired place. I am going insane with MS doc and tutorial never show my case.

Desired Location

My desire is to locate here: Desired location Image basically the desired experience should be:

  1. You go to Solution Explorer
  2. You righ-click on the Azure Function Project
  3. You find the "Add" menu group and click it
  4. You will find the firs item is "Add new Azure Function"
  5. After that you should find my custom button, the "Add new Custom Azure Function"

Actual Location

Unfortunately I find it here: Actual location image the experience is:

  1. You go to Solution Explorer
  2. You righ-click on the Azure Function Project
  3. You find the custom button at the 6th menu group

Code

This is my VSCommandTable.vsct file:

<?xml version="1.0" encoding="utf-8"?>
<CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable" xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <Extern href="stdidcmd.h"/>
    <Extern href="vsshlids.h"/>
    <Include href="KnownImageIds.vsct"/>
    <Include href="VSGlobals.vsct"/>

    <Commands package="AzureFunctionScaffoldingPOCExtension">
        <Groups>
            <Group guid="AzureFunctionScaffoldingPOCExtension" id="MyMenuGroup" priority="0x0400">
                <!--This one should be the "Add" submenu I am looking for, but actually just goes into the righ-click on project in Solution Explorer-->
                <Parent guid="guidSHLMainMenu" id="IDG_VS_PROJ_ADD"/>
            </Group>
        </Groups>

        <Buttons>
            <Button guid="AzureFunctionScaffoldingPOCExtension" id="MyCommand" priority="0x0100" type="Button">
                <!--This one should reference the Custom Group, right? Or since it is just a button the Group element is not necessary and this should provide the actual parent element?-->
                <Parent guid="AzureFunctionScaffoldingPOCExtension" id="MyMenuGroup"/>
                <Icon guid="ImageCatalogGuid" id="AddModule" />
                <CommandFlag>IconIsMoniker</CommandFlag>
                <CommandFlag>DynamicVisibility</CommandFlag>
                <Strings>
                    <ButtonText>Add Custom Azure Function</ButtonText>
                    <LocCanonicalName>.AzureFunctionScaffoldingPOCExtension.MyCommand</LocCanonicalName>
                </Strings>
            </Button>
        </Buttons>
    </Commands>

    <VisibilityConstraints>
        <VisibilityItem guid="AzureFunctionScaffoldingPOCExtension" id="MyCommand" context="UICONTEXT_SolutionExists"/>
    </VisibilityConstraints>

    <Symbols>
        <GuidSymbol name="AzureFunctionScaffoldingPOCExtension" value="{4cb051a6-eb41-455d-80e2-433571ee2b43}">
            <IDSymbol name="MyMenuGroup" value="0x0001" />
            <IDSymbol name="MyCommand" value="0x0100" />
        </GuidSymbol>
        <GuidSymbol name="guidSHLMainMenu" value="{D309F791-903F-11D0-9EFC-00A0C911004F}">
            <IDSymbol name="IDG_VS_PROJ_ADD" value="0x0402"/>
        </GuidSymbol>
    </Symbols>

</CommandTable>

Anything else seems to work.

I have tried to let the Group inherits from VSMainMenu but it doesn't work as well, can't understand why.

If you can also tell me what is the process, the method, to identify the id and the guid of a certain element, submenu etc it would be awesome. I tried reading MS Doc but I can't understand how to scientifically locate ids, and also is the "ProjectNode/Add" submenu a menu or not since it is in SolutionExplorer which is technically a Toolbar?


Solution

  • If you want to put your button in "ProjectNode/Add/ submenu", you can follow below steps:

    Test result:

    enter image description here

    1.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 addCustomContextMenu values.

    <GuidSymbol name="IDG_VS_PROJ_ADD" value="{D309F791-903F-11D0-9EFC-00A0C911004F}">
     <IDSymbol name="addCustomContextMenu" value="0x352"/>
    </GuidSymbol>
    

    You can get Guid and Command ID by this thread to identify menus and commands in my VS2022 community and it prints GUID and the CommandID in dialog.

    enter image description here

    2.Reference this group as a parent for your command group (MyMenuGroup) in the Groups section:

    <Group guid="guidVSIXProject2PackageCmdSet" id="MyMenuGroup" priority="0x0600">
           <Parent guid="IDG_VS_PROJ_ADD" id="addCustomContextMenu"/>
     </Group>
    

    VSCommandTable.vsct file demo:

    <?xml version="1.0" encoding="utf-8"?>
    <CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    
        <Extern href="stdidcmd.h"/>
        <Extern href="vsshlids.h"/>
        <Include href="KnownImageIds.vsct"/>
        <Include href="VSGlobals.vsct"/>
    
        <Commands package="AzureFunctionScaffoldingPOCExtension">
            <Groups>
                <Group guid="AzureFunctionScaffoldingPOCExtension" id="MyMenuGroup" priority="0x0400">
                  
                    <Parent guid="IDG_VS_PROJ_ADD" id="addCustomContextMenu"/>
                </Group>
            </Groups>
    
            <Buttons>
                <Button guid="AzureFunctionScaffoldingPOCExtension" id="MyCommand" priority="0x0100" type="Button">
                    <!--This one should reference the Custom Group, right? Or since it is just a button the Group element is not necessary and this should provide the actual parent element?-->
                    <Parent guid="AzureFunctionScaffoldingPOCExtension" id="MyMenuGroup"/>
                    <Icon guid="ImageCatalogGuid" id="AddModule" />
                    <CommandFlag>IconIsMoniker</CommandFlag>
                    <CommandFlag>DynamicVisibility</CommandFlag>
                    <Strings>
                        <ButtonText>Add Custom Azure Function</ButtonText>
                        <LocCanonicalName>.AzureFunctionScaffoldingPOCExtension.MyCommand</LocCanonicalName>
                    </Strings>
                </Button>
            </Buttons>
        </Commands>
    
        <VisibilityConstraints>
            <VisibilityItem guid="AzureFunctionScaffoldingPOCExtension" id="MyCommand" context="UICONTEXT_SolutionExists"/>
        </VisibilityConstraints>
    
        <Symbols>
            <GuidSymbol name="AzureFunctionScaffoldingPOCExtension" value="{4cb051a6-eb41-455d-80e2-433571ee2b43}">
                <IDSymbol name="MyMenuGroup" value="0x0001" />
                <IDSymbol name="MyCommand" value="0x0100" />
            </GuidSymbol>
           <GuidSymbol name="IDG_VS_PROJ_ADD" value="{D309F791-903F-11D0-9EFC-00A0C911004F}">
               <IDSymbol name="addCustomContextMenu" value="0x352"/>
            </GuidSymbol>
        </Symbols>
    </CommandTable>