2010-06-10 22 views
45

Quiero agregar una nueva opción en el menú contextual del explorador de soluciones de Visual Studio 2010 para un tipo de archivo específico. Entonces, por ejemplo, al hacer clic derecho en un archivo * .cs se mostrará el menú contextual existente más "mi nueva opción".Complemento Visual Studio 2010 - Agregar un menú contextual al Explorador de soluciones

Me pregunto cómo se vería el código; y me encantaría un puntero a una buena referencia para desarrollar plug-ins de Visual Studio. Los tutoriales/referencias que estoy viendo son llamativamente horribles.

Gracias!

Respuesta

16

Descubrí que la mejor manera de hacerlo era crear un paquete de Visual Studio en lugar de un complemento de Visual Studio. La experiencia de implementación de vsix es tan ingeniosa: todo fue una experiencia realmente fácil. Solo es compatible con Visual Studio 2010, pero eso fue lo suficientemente bueno en mi caso.

Aquí es el VSCT resultante:

<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

Gracias, esto es muy útil; ¿cómo manejó la DynamicVisibility para el elemento de menú? –

3

ACTUALIZACIÓN:

GAX/GAT para VS2010 también disponible de http://msdn.microsoft.com/en-us/library/ff687173

Post original

Bien es horrible porque VS es realmente compleja. Usar GAX/GAT fue posible, pero está no VS2010 Version yet. Lo que sugiero es que descargue algunas muestras del Visual Studio Gallery para tratar de comprender cómo funciona todo, por desgracia, no es una tarea fácil.

HTH

+0

1 Su realmente no es una mala idea, especialmente para cosas más complejas que hay. Recomiendo hacer esto después de que aprendas lo básico. – Terrance

32

Me tomó cerca de 5 horas para hacer esto.

Hay 2 opciones, Complemento de Visual Studio (o complemento compartido) versus paquete de Visual Studio.

El paquete es mucho más complicado para brindarle más control, pero para un menú contextual en el explorador de soluciones no es necesario.

Proyecto tan nuevo-> Otros tipos de proyectos -> Extensibilidad -> Complemento de Visual Studio.

Aquí hay un recorrido - Link

También Éste He seguido algunos - Link

le recomiendo que deje en la opción para añadir al menú herramientas hasta que tenga el trabajo menú contextual, o para proporcionar . un lugar para poner un diálogo de configuración (si no se escribe una página de opciones> Herramientas-

Aquí está el código de conexión:

_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. 
      } 
     } 
    } 

Este código comprueba si lo que el usuario ha seleccionado es un proyecto, por ejemplo:

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

Tenga en cuenta que ciertos nombres de cadena en su código tienen que coincidir y no estoy seguro de cuáles son todavía bastante como acabo de hacer esto ayer.

+0

Y esta referencia parece tener un código que está muy cerca de su código de conexión. Me ayudó cuando estaba viendo tu ejemplo, http://msdn.microsoft.com/en-us/library/90855k9f%28VS.80%29.aspx – Terrance

+0

gracias, eso era exactamente lo que necesitaba. – dmihailescu

2

me encontré tener que añadir un elemento a la ventana del editor de código de menú contextual, que terminó siendo cmdBars["Script Context"] como yo quería que específicamente para los archivos de JavaScript.

Como una técnica para encontrar este, que me sentí intercambio útil, añade el nuevo elemento de menú para todos (456) los controles de menú en el estudio visual con el siguiente bucle:

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

continuación enangosté esta utilizando una Dividir y conquistar la técnica mediante el ajuste de los límites del bucle:

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

Hasta que finalmente encontré lo que estaba buscando.

(La pregunta relacionada con este está en Visual Studio 2010 Plug-in - Adding a context-menu to the Editor Window)

Cuestiones relacionadas