Preguntas más frecuentes: Convertir complementos en extensiones de VSPackage

Los complementos están desusados. Para crear una nueva extensión de Visual Studio, es necesario crear un VSPackage. Si ya tiene un complemento, puede que siga funcionando, pero si quiere distribuirlo, deberá convertirlo a un VSPackage. Estas son las respuestas a algunas preguntas frecuentes sobre cómo convertir un complemento de Visual Studio en una extensión VSPackage.

Importante

En muchos casos, simplemente puede transferir el código de complemento a un proyecto de VSPackage.Puede obtener el objeto de automatización DTE mediante una llamada a GetService en el método Initialize.

DTE2 dte = (DTE2)GetService(typeof(DTE));

Para obtener más información, vea ¿Cómo puedo ejecutar el código de mi complemento en un VSPackage? a continuación.

¿Qué software necesito para desarrollar extensiones VSPackage?

Necesita instalar el SDK de Visual Studio 2013 además de la edición Professional, Premium o Ultimate de Visual Studio 2013. Puede descargar el SDK de la página SDK de Visual Studio 2013, en el sitio web Centro de descarga de Microsoft. Le recomendamos que instale el SDK antes de instalar Visual Studio 2013 Update 2.

¿Dónde está la documentación de VSPackage?

Comience con Información general de Visual Studio que extiende. Ese artículo contiene otros artículos sobre la implementación de VSPackage.

¿Puedo convertir mi proyecto de complemento en un proyecto de VSPackage?

Un proyecto de complemento no se puede convertir en un proyecto de VSPackage porque los mecanismos que se usan en los proyectos de VSPackage no son los mismos que los de los proyectos de complemento. La plantilla de proyecto VSPackage incluye bastante código que hace que resulte relativamente fácil ponerlo en marcha como extensión VSPackage.

¿Cómo comienzo a desarrollar extensiones VSPackage?

La plantilla de proyecto para las extensiones VSPackage tiene los elementos que necesita. Así se crea un VSPackage que incluye un comando de menú:

Para crear un VSPackage que tiene un comando de menú

  1. Cree un proyecto de Paquete de Visual Studio y asígnele el nombre TestVSPackage. (Archivo, Nuevo, Proyecto, o escriba proyecto en la ventana Inicio rápido). En el cuadro de diálogo Nuevo proyecto, expanda Otros tipos de proyectos, Extensibilidad y, después, seleccione Paquete de Visual Studio. Asigne al proyecto el nombre TestVSPackage y especifique una ubicación para él.

  2. Se muestra el Asistente para paquetes de Visual Studio. En la página Seleccione un lenguaje de programación, seleccione C# como lenguaje. Mantenga seleccionada la opción Generar una clave nueva. En la página Opciones de VSPackage, seleccione Comando de menú. Elija el botón Finalizar.

  3. Presione F5 para compilar y ejecutar el proyecto en modo de depuración.

    Se muestra una segunda instancia de Visual Studio. Esta segunda instancia se llama instancia experimental, y puede que no tenga la misma configuración que la instancia de Visual Studio que está usando para escribir código. La primera vez que ejecute la instancia experimental se le pedirá que inicie sesión en VS Online y especifique el tema y el perfil.

    En el menú Herramientas (en la instancia experimental), verá un botón llamado My Command name. Al seleccionar este botón, debería aparecer un mensaje: Dentro de TestVSPackagePackage.MenuItemCallback().

¿Cómo puedo ejecutar el código de mi complemento en un VSPackage?

Normalmente, el código de complemento normalmente se ejecuta de una de dos maneras:

  • Se desencadena mediante un comando de menú (el código está en el método IDTCommandTarget.Exec)

  • Automáticamente en el inicio (el código está en el controlador del evento OnConnection).

Puede hacer las mismas cosas en un VSPackage. Aquí se indica cómo agregar código de complemento en el método de devolución de llamada:

Para implementar un comando de menú en un VSPackage

  1. Cree un VSPackage que tenga un comando de menú. (Vea ¿Cómo comienzo a desarrollar extensiones VSPackage?).

  2. Abra el archivo que contiene la definición del VSPackage. (En un proyecto de C#, es <su nombre de proyecto>Package.cs).

  3. Agregue las siguientes instrucciones using al archivo:

    using EnvDTE;
    using EnvDTE80;
    
  4. Busque el método MenuItemCallback. Agregue una llamada a GetService para obtener el objeto DTE2:

    DTE2 dte = (DTE2)GetService(typeof(DTE));
    
  5. Agregue el código que el complemento tenía en su método IDTCommandTarget.Exec. Por ejemplo, este es un código que agrega un nuevo panel a la ventana Output e imprime "Some Text" en el nuevo panel.

    private void MenuItemCallback(object sender, EventArgs e)
    {
        DTE2 dte = (DTE2) GetService(typeof(DTE));
        OutputWindow outputWindow = dte.ToolWindows.OutputWindow;
    
        OutputWindowPane outputWindowPane = outputWindow.OutputWindowPanes.Add("A New Pane");
        outputWindowPane.OutputString("Some Text");
    }
    
  6. Compile y ejecute este proyecto. Presione F5 o seleccione Iniciar en la barra de herramientas Depurar. En la instancia experimental de Visual Studio, el menú Herramientas debería tener un botón llamado My Command name. Cuando elija este botón, las palabras Some Text deberían aparecer en un panel de la ventana Output. (Puede que tenga que abrir la ventana Output).

También puede hacer que el código se ejecute en el inicio. Sin embargo, normalmente eso se desaconseja para las extensiones VSPackage. Si se intentan cargar demasiadas extensiones cuando se inicia Visual Studio, el tiempo de inicio será notablemente mayor. El procedimiento recomendado es cargar el VSPackage automáticamente solo cuando se cumpla alguna condición (por ejemplo, que se abra una solución).

Este procedimiento muestra cómo ejecutar código de complemento en un VSPackage que se carga automáticamente cuando se abre una solución:

Para cargar automáticamente un VSPackage

  1. Cree un proyecto de paquete de Visual Studio. (Para las instrucciones correspondientes, vea ¿Cómo comienzo a desarrollar extensiones VSPackage?. Asigne al proyecto el nombre TestAutoload y especifique una ubicación para él.

  2. Se muestra el Asistente para paquetes de Visual Studio. En la página Seleccione un lenguaje de programación, seleccione C# como lenguaje y mantenga seleccionada la opción Generar una clave nueva. Elija Finalizar.

  3. Abra TestAutoloadPackage.cs. Encuentre la línea donde se declara la clase de paquete:

    public sealed class <name of your package>Package : Package
    
  4. Por encima de esta línea hay un conjunto de atributos. Agregue este atributo:

    [ProvideAutoLoad(UIContextGuids80.SolutionExists)]
    
  5. Establezca un punto de interrupción en el método Initialize() e inicie la depuración (F5).

  6. En la instancia experimental, abra un proyecto. El VSPackage se cargará y se alcanzará el punto de interrupción.

Para especificar otros contextos en los que cargar su VSPackage, puede usar los campos de UIContextGuids80. Para obtener más información, vea Cómo: Cargar automáticamente un VSPackage.

¿Cómo obtengo el objeto DTE?

Si el complemento no muestra una interfaz de usuario (por ejemplo, comandos de menú, botones de barra de herramientas o ventanas de herramienta) quizás pueda usar el código tal cual siempre que obtenga el objeto de automatización DTE del VSPackage. Esta es la manera de hacerlo:

Para obtener el objeto DTE de un VSPackage

  1. En una solución de VSPackage, busque el archivo <nombre del proyecto>Package.cs. Esta es la clase que deriva de Package; puede ayudarlo a interaccionar con Visual Studio. En este caso, usa su GetService para obtener el objeto DTE2.

  2. Agregue estas instrucciones using:

    using EnvDTE;
    using EnvDTE80;
    
  3. Busque el método Initialize. Este método controla el comando que especificó en el asistente para paquetes. Agregue una llamada a GetService para obtener el objeto DTE:

    DTE dte = (DTE)GetService(typeof(DTE));
    

Cuando tenga el objeto de automatización DTE, puede agregar el resto del código de complemento al proyecto. Si necesita el objeto DTE2, puede hacer lo mismo.

¿Cómo cambio los comandos de menú y los botones de barra de herramientas en mi complemento al estilo de VSPackage?

Las extensiones VSPackage usan el archivo .vsct para crear la mayoría de los comandos de menú, barras de herramientas, botones de barra de herramientas y otras interfaces de usuario. La plantilla de proyecto VSPackage le da la opción de crear un comando en el menú Herramientas. Para obtener más información, vea tutorial: Crear un comando de menú mediante la plantilla de paquete de Visual Studio.

Para obtener más información sobre los archivos .vsct, vea Cómo VSPackages agrega elementos de la interfaz de usuario al IDE. Para obtener tutoriales que muestran cómo usar el archivo .vsct para agregar elementos de menú, barras de herramientas y botones de barra de herramientas, vea Tutoriales para los comandos, menús, barras de herramientas y

¿Cómo agrego ventanas de herramienta personalizadas a la manera de VSPackage?

La plantilla de proyecto VSPackage le da la opción de crear una ventana de herramienta. Para obtener más información, vea ventanas de herramientas y los artículos que incluye, especialmente Cómo: cree una ventana de herramientas.

¿Cómo administro las ventanas de Visual Studio a la manera de VSPackage?

Si su complemento administra las ventanas de Visual Studio, el código de complemento debería funcionar en un VSPackage. Por ejemplo, este procedimiento muestra cómo agregar código que administra la Lista de tareas al método MenuItemCallback del VSPackage.

Para insertar código de administración de ventanas desde un complemento en un VSPackage

  1. Cree un VSPackage que tenga comando de menú, como en la sección ¿Cómo comienzo a desarrollar extensiones VSPackage?.

  2. Abra el archivo que contiene la definición del VSPackage. (En un proyecto de C#, es <su nombre de proyecto>Package.cs).

  3. Agregue estas instrucciones using:

    using EnvDTE;
    using EnvDTE80;
    
  4. Busque el método MenuItemCallback. Agregue una llamada a GetService para obtener el objeto DTE2:

    DTE2 dte = (DTE2)GetService(typeof(DTE));
    
  5. Agregue el código de su complemento. Por ejemplo, este es un código que agrega nuevas tareas a la Lista de tareas, indica el número de tareas y elimina una de ellas.

    private void MenuItemCallback(object sender, EventArgs e) 
    {
        DTE2 dte = (DTE2) GetService(typeof(DTE)); 
    
        TaskList tl = (TaskList)dte.ToolWindows.TaskList; 
        askItem tlItem; 
    
        // Add a couple of tasks to the Task List. 
        tlItem = tl.TaskItems.Add(" ", " ", "Test task 1.",  
            vsTaskPriority.vsTaskPriorityHigh, vsTaskIcon.vsTaskIconUser, 
            true, "", 10, true, true);
        tlItem = tl.TaskItems.Add(" ", " ", "Test task 2.", 
            vsTaskPriority.vsTaskPriorityLow, vsTaskIcon.vsTaskIconComment, true, "", 20, true,true);
    
        // List the total number of task list items after adding the new task items.
        System.Windows.Forms.MessageBox.Show("Task Item 1 description: "+tl.TaskItems.Item(2).Description);
        System.Windows.Forms.MessageBox.Show("Total number of task items: "+tl.TaskItems.Count); 
    
        // Remove the second task item. The items list in reverse numeric order. 
        System.Windows.Forms.MessageBox.Show("Deleting the second task item");
        tl.TaskItems.Item(2).Delete();
        System.Windows.Forms.MessageBox.Show("Total number of task items: "+tl.TaskItems.Count); 
    }
    

¿Cómo administro proyectos y soluciones en un VSPackage?

Si su complemento administra proyectos y soluciones, el código de complemento debería funcionar en un VSPackage. Por ejemplo, este procedimiento muestra cómo agregar código que obtiene el proyecto de inicio.

  1. Cree un VSPackage que tenga comando de menú, como en la sección ¿Cómo comienzo a desarrollar extensiones VSPackage?.

  2. Abra el archivo que contiene la definición del VSPackage. (En un proyecto de C#, es <su nombre de proyecto>Package.cs).

  3. Agregue estas instrucciones using:

    using EnvDTE;
    using EnvDTE80;
    
  4. Busque el método MenuItemCallback. Agregue una llamada a GetService para obtener el objeto DTE2:

    DTE2 dte = (DTE2)GetService(typeof(DTE));
    
  5. Agregue el código de su complemento. Por ejemplo, el siguiente código obtiene el nombre del proyecto de inicio en una solución. (Se debe abrir una solución multiproyecto cuando este paquete se ejecuta).

    private void MenuItemCallback(object sender, EventArgs e)
    {
        DTE2 dte = (DTE2) GetService(typeof(DTE)); 
    
        SolutionBuild2 sb = (SolutionBuild2)dte.Solution.SolutionBuild; 
        Project startupProj; 
        string msg = "";
    
        foreach (String item in (Array)sb.StartupProjects) 
        {
            msg += item; 
        }
        System.Windows.Forms.MessageBox.Show("Solution startup Project: "+msg); 
        startupProj = dte.Solution.Item(msg); 
        System.Windows.Forms.MessageBox.Show("Full name of solution's startup project: "+"/n"+startupProj.FullName); 
    }
    

¿Cómo establezco métodos abreviados de teclado en un VSPackage?

Se usa el elemento <KeyBindings> del archivo .vsct. En el ejemplo siguiente, el método abreviado de teclado para el comando idCommand1 es Alt+A, y el método abreviado de teclado para el comando idCommand2 es Alt+Ctrl+A. Tenga en cuenta la sintaxis de los nombres de clave.

<KeyBindings>
    <KeyBinding guid="MyProjectCmdSet" id="idCommand1" editor="guidVSStd97" key1="A" mod1="ALT" />
    <KeyBinding guid="MyProjectCmdSet" id="idCommand2" editor="guidVSStd97" key1="A" mod1="CONTROL" mod2="ALT" />
</KeyBindings>

¿Cómo administro los eventos de automatización en un VSPackage?

Los eventos de automatización en un VSPackage se controlan de la misma manera que en el complemento. En el código siguiente se muestra cómo controlar el evento OnItemRenamed. (En el ejemplo se da por hecho que ya ha obtenido el objeto DTE).

Events2 dteEvents = (Events2)dte.Events;
dteEvents.ProjectItemsEvents.ItemRenamed += listener1.OnItemRenamed; 
. . .
public void OnItemRenamed(EnvDTE.ProjectItem projItem, string oldName) 
{
    string s = "[Event] Renamed " + oldName + " to " + Path.GetFileName(projItem.get_FileNames(1) + " in project " + projItem.ContainingProject.Name; 
}