Compartir a través de


Visual Studio 2013

Ampliación de Visual Studio 2013 con extensiones

Doug Erickson
Susan Norwood

Una de las mejores características de las versiones de alto nivel de Visual Studio está ahora disponible para todo el mundo, de forma gratuita, mediante el IDE de Visual Studio Community 2013: la capacidad de usar extensiones desde la Galería de Visual Studio (encuentre las extensiones en bit.ly/115mBzm). ¿Qué son las extensiones? Son complementos que le permiten ampliar Visual Studio Community 2013 (que puede descargar en bit.ly/1tH2uyc) y características de Visual Studio para realizar nuevas tareas, agregar nuevas características y refactorizar código (o incluso admitir nuevos lenguajes).

La comunidad de desarrolladores de Microsoft ofrece una amplia variedad de extensiones en la Galería de Visual Studio. Eche un vistazo: se sorprenderá de todos los tipos de extensiones disponibles. Algunas de ellas, como la extensión de Productivity Power Tools 2013 (que puede descargar en bit.ly/1xE3EAT), entrarán en su vida para nunca irse. Puede instalar estas extensiones desde Internet, o puede buscar extensiones en línea en Visual Studio con la ventana Extensiones y actualizaciones, en el menú Herramientas. Mire la categoría En línea para encontrar más herramientas populares, como Visual Assist y ReSharper. Incluso puede encontrar más extensiones en la Galería de códigos (bit.ly/11nzi9Q).

Puede que incluso las mejores herramientas no se adapten a la perfección a tareas específicas que desee realizar o automatizar en el IDE. Es probable que tenga sus propias secuencias de comandos personales, que haya personalizado y modificado para hacer su trabajo más sencillo. Puede que tenga una que compruebe un directorio de compilación para una compilación correcta, que ejecute una transformación en archivos XML o limpie todos los restos de un proceso de compilación complejo. ¿Cómo le gustaría ejecutar su herramienta en Visual Studio, como parte del IDE o como parte de su proceso de compilación? Ahora puede hacerlo con Visual Studio Community 2013 y con el SDK de Visual Studio 2013.

Puede empezar descargando el SDK de Visual Studio. Proporciona todas las bibliotecas, herramientas y plantillas de proyectos para crear una gran variedad de distintas extensiones. Continúe, instálelo y ya estará listo para empezar.

Configurar herramientas para su ejecución en Visual Studio

Una vez que tenga el SDK instalado, es bastante fácil hacer que su herramienta o su script se ejecuten desde un menú de Visual Studio. El omnipresente Notepad.exe servirá de ejemplo para este artículo, pero puede usar cualquier ejecutable o integrar su propio código en el controlador de comando.

Una extensión básica es un binario de paquetes de Visual Studio. Puede encontrar la plantilla de paquetes de Visual Studio en el cuadro de diálogo Nuevo proyecto, en Visual Basic | Extensibilidad, C# | Extensibilidad, u Otros tipos de proyectos | Extensibilidad.

Este artículo le mostrará cómo hacer una extensión sencilla que inicie el Bloc de notas. Usaremos la plantilla de C#/Extensibilidad para crear un proyecto de paquetes de Visual Studio en C#. Lo colocaremos en el directorio D:\Code y lo llamaremos StartNotepad. Al final, esta extensión iniciará Notepad desde un elemento de menú IDE de Visual Studio.

Una vez que haga doble clic en la plantilla, Visual Studio inicia un asistente para ayudarle a configurar la extensión. Para principiantes, basta con aceptar los valores predeterminados en las dos primeras páginas de cuadros de diálogo.

Después, realice los siguientes pasos:

  1. En la página Seleccionar opciones del paquete de VS, seleccione la opción Comando de menú.
  2. En la página Opciones de comando, establezca el nombre de comando en Iniciar Bloc de notas y el id. de comando en cmdidStartNotepad.
  3. En la página Opciones de prueba, desactive las dos casillas.
  4. Haga clic en Finalizar.

En este punto, podrá compilar y ejecutar el proyecto del paquete. Cuando el proyecto se abra, empiece a depurar (presione la tecla F5 o use el comando Inicio de la barra de herramientas). Aparecerá una nueva instancia de Visual Studio Community 2013. Cuando haya completado esto, verá el IDE, con un valor predeterminado de página Inicio – Microsoft Visual Studio – Instancia experimental en la barra del título (vea la Ilustración 1). Esta es su instancia de prueba de Visual Studio. Se ejecuta de forma independiente de su instancia de trabajo de Visual Studio, por lo que no tiene que preocuparse por contaminar su propio entorno de desarrollo si algo va mal.

La instancia experimental de Visual Studio
Ilustración 1: La instancia experimental de Visual Studio

La “instancia experimental” es realmente una forma elegante de anunciar que ha iniciado una instancia de espacio aislado de Visual Studio para probar su extensión. Tiene todas las funciones de Visual Studio Community 2013, pero no pone en peligro su trabajo en la instancia original de Visual Studio. Para un ejemplo tan simple, esto puede parecer excesivo. Sin embargo, si compila todo un marco de diseño o un conjunto complejo interdependiente de herramientas de compilación, no querrá arriesgar su código ejecutándolo en la misma instancia que en la que está desarrollando.

En el menú Herramientas de la instancia experimental, abra la ventana Extensiones y actualizaciones. Debería ver aquí la extensión StartNotepad (vea la Ilustración 2). (Si abre Extensiones y actualizaciones en su instancia de trabajo de Visual Studio, no verá StartNotePad).

Extensiones y actualizaciones, que muestra StartNotepad
Ilustración 2: Extensiones y actualizaciones, que muestra StartNotepad

También verá Iniciar Bloc de notas en el menú Herramientas (vea la Ilustración 3).

Nueva confirmación de elemento de menú para StartNotepad en Herramientas
Ilustración 3: Nueva confirmación de elemento de menú para StartNotepad en Herramientas

Ahora vaya al menú Herramientas en la instancia experimental. Debería ver el comando Iniciar Bloc de notas. En este punto, aparecerá un cuadro de mensaje con “StartNotepad – Inside MSIT.StartNotepad.StartNotepadPackage.MenuItemCallback()”. Verá cómo iniciar realmente el Bloc de notas desde este comando en la siguiente sección.

Configurar el comando de menú

Detenga la depuración y vuelva a su instancia de trabajo de Visual Studio. Abra el archivo StartNotepadPackage.cs, que contiene la clase derivada Package. Este es el punto inicial para todas las extensiones VSPackage. El método Initialize de esta clase configura el comando:

// Add our command handlers for menu (commands must exist in the .vsct file)
OleMenuCommandService mcs =
  GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
if ( null != mcs )
{
  // Create the command for the menu item.
  CommandID menuCommandID = new CommandID(GuidList.guidStartNotepadCmdSet,
    (int)PkgCmdIDList.cmdidStartNotepad);
  MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID );
  mcs.AddCommand( menuItem );
}

No se preocupe por los detalles de este código ahora mismo. Observará que es como se instancia el comando de menú. Los menús y demás elementos de la IU de las extensiones de VSPackage se definen, como indica el comentario del código, en el archivo .vsct.

El controlador de comandos se denomina MenuItemCallback (en la misma clase StartNotepadPackage). Elimine el método existente y agregue el siguiente:

private void MenuItemCallback(object sender, EventArgs e)
{
  Process proc = new Process();
  proc.StartInfo.FileName = "notepad.exe";
  proc.Start();
}

Ahora, pruébelo. Al empezar a depurar el proyecto y hacer clic en Herramientas | Iniciar Bloc de notas, debería ver una instancia del Bloc de notas. De hecho, obtendrá una nueva instancia del Bloc de notas cada vez que haga clic en Iniciar Bloc de notas. 

Puede usar una instancia de la clase System.Diagnostics.Process para usar cualquier ejecutable, no solo Notepad. Pruébelo con calc.exe, por ejemplo.

Definir la interfaz

Ahora usará el archivo .vsct para definir la IU para su extensión. Eche un vistazo al archivo StartNotepad.vsct. Es un lugar práctico para encontrar todas las definiciones de la IU de Visual Studio que usará en su extensión. Es un archivo XML, así que prepárese para los paréntesis angulares.

Busque el bloque <Groups>. Cada comando de menú debe pertenecer a un grupo, lo que indica a Visual Studio dónde colocar el comando. En este caso, el comando está en el menú Herramientas, y su elemento principal es el menú principal:

<Groups>
  <Group guid="guidStartNotepadCmdSet" 
    id="MyMenuGroup" priority="0x0600">
    <Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_TOOLS"/>
  </Group>
</Groups>

No se preocupe demasiado por los detalles aún. Esto es solo para mostrarle dónde se encuentran los elementos importantes. El comando en sí se define en el bloque <Buttons>:

<Button guid="guidStartNotepadCmdSet" id="cmdidStartNotepad"
  priority="0x0100" type="Button">
  <Parent guid="guidStartNotepadCmdSet" id="MyMenuGroup" />
  <Icon guid="guidImages" id="bmpPic1" />
  <Strings>
    <ButtonText>Start Notepad</ButtonText>
  </Strings>
</Button>

Puede ver que el botón está definido con un GUID (guidStartNotepadCmdSet, que es el mismo que el GUID Group) y un id. (cmdidStartNotepad, el que especificó en el asistente de paquetes). El comando es un elemento principal de Group. Tiene un icono y texto. El icono es uno pertenece a un conjunto predeterminado de iconos incluido en la solución. La prioridad especifica la ubicación de este botón en el menú, si hay varios comandos en el grupo de comandos. Los GUID e id. de los grupos y botones se definen en el bloque <Symbols>:

<!-- This is the package GUID. -->
<GuidSymbol name="guidStartNotepadPkg"
  value="{18311db7-ca0f-419c-82b0-5aa14c8b541a}" />
<!-- This is the GUID used to group the menu commands together -->
<GuidSymbol name="guidStartNotepadCmdSet"
  value="{b0692a6d-a8cc-4b53-8b2d-17508c87f1ab}">
  <IDSymbol name="MyMenuGroup" value="0x1020" />
  <IDSymbol name="cmdidStartNotepad" value="0x0100" />
</GuidSymbol>

Los mapas de bits también se definen en el bloque <Symbols>:

<GuidSymbol name="guidImages" 
  value="{b8b810ad-5210-4f35-a491-c3464a612cb6}" >
  <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" />
  <IDSymbol name="bmpPicStrikethrough" value="6" />
</GuidSymbol>

Pruebe a cambiar el icono a uno de los definidos aquí. Ninguna de las opciones son especialmente adecuadas para el Bloc de notas, así que elija el tachado, ya que muestra otra parte de la configuración. Aunque los iconos están definidos en el bloque <Symbols>, también deben aparecer en el atributo usedList del bloque <Bitmaps>:

<Bitmap guid="guidImages" href="Resources\Images.png" usedList="bmpPic1,
  bmpPic2, bmpPicSearch, bmpPicX, bmpPicArrows"/>

Verá que bmpPicStrikethrough no está enumerado, aunque se ha definido. Si cambia el icono a este mapa de bits, no aparecerá en el menú. Por tanto, agregue bmpPicStrikethrough:

<Bitmap guid="guidImages" href="Resources\Images.png" usedList="bmpPic1,
  bmpPic2, bmpPicSearch, bmpPicX, bmpPicArrows, bmpPicStrikethrough"/>

Ahora puede cambiar el icono a bmpPicStrikethrough para el botón del menú:

<Button guid="guidStartNotepadCmdSet" id="cmdidStartNotepad"
  priority="0x0100" type="Button">
  <Parent guid="guidStartNotepadCmdSet" id="MyMenuGroup" />
  <Icon guid="guidImages" id="bmpPicStrikethrough" />
  <Strings>
    <ButtonText>Start Notepad</ButtonText>
  </Strings>
</Button>

Ya puede probarlo. Cuando aparezca la instancia experimental, debería ver algo como la Ilustración 4 en el menú de Herramientas.

Comando para iniciar el Bloc de notas
Ilustración 4: Comando para iniciar el Bloc de notas

Ahora, agregue un método abreviado del teclado para el comando del menú Iniciar Bloc de notas. Este ejemplo usará Ctrl+1. Si agrega un método abreviado de teclado, asegúrese de usar una combinación un poco enrevesada para que su comando no entre en conflicto con una combinación más estándar. Puede hacer todo esto en el archivo .vsct. Los métodos abreviados de teclado se denominan KeyBindings en el archivo .vsct. Agregue el siguiente bloque al archivo .vsct:

<KeyBindings>
  <KeyBinding guid="guidStartNotepadCmdSet" 
    id="cmdidStartNotepad"    
    editor="guidVSStd97" key1="1" mod1="CONTROL"/>
</KeyBindings>

El atributo key1 declara la tecla estándar y el atributo mod1 declara la tecla del modificador o acelerador (normalmente, Ctrl, Alt o Mayús) que se presiona junto con la tecla estándar. Si agrega mod2="ALT" para agregar una segunda tecla de modificador, debería tener Ctrl+Alt+1 como método abreviado. Quédese con Ctrl+1 de momento. Tenga en cuenta, no obstante, que el archivo .vsct es un buen lugar para empezar sus personalizaciones. Ahora, puede comenzar a depurar. Vuelva a iniciar el paquete. Cuando aparezca la instancia experimental, presione Ctrl+1. Debería obtener una instancia del Bloc de notas.

Mantener la capacidad de respuesta de la IU

El método MenuItemCallback, tal y como existe actualmente, no bloquea el subproceso de la IU. Aun así, puede iniciar el Bloc de notas con el comando Iniciar bloc de notas (o Ctrl+1). También puede seguir trabajando en el IDE de Visual Studio. Puede mover la ventana, hacer clic en otros comandos de los menús, etc. Imagine que su herramienta necesita realizar su trabajo antes de salir del controlador. En otras palabras, debe llamar a Process.WaitForExit.

Por desgracia, si llama a WaitForExit en el subproceso de IU de Visual Studio, tal y como MenuItemCallback está haciendo en este punto, toda la IU de Visual Studio se congelará. Pruébelo en acción. En el método MenuItemCallback, llame a WaitForExit:

private void MenuItemCallback(object sender, EventArgs e)
{
  Process proc = new Process();
  proc.StartInfo.FileName = "notepad.exe";
  proc.Start();
  proc.WaitForExit();
}

Comience la depuración y, cuando aparezca la instancia experimental, presione Ctrl+1. Debería ver la instancia del Bloc de notas. Ahora, pruebe a mover la ventana de Visual Studio (la experimental). No se moverá. No puede hacer nada más en la IU de Visual Studio, de hecho. Incluso puede ver el mensaje emergente que dice que Microsoft Visual Studio está ocupado. Claramente, es algo que debe solucionar.

Afortunadamente, la solución es sencilla. Si tiene una herramienta o un proceso que tardará una cantidad considerable de tiempo en completarse, colóquelo en una tarea en MenuItemCallback, de esta forma:

private void MenuItemCallback(object sender, EventArgs e)
{
  ThreadHelper.JoinableTaskFactory.RunAsync(async delegate
  {
    Process proc = new Process();
    proc.StartInfo.FileName = "notepad.exe";
    proc.Start();
    await proc;
  });
}

Ahora debería poder ejecutar su herramienta y trabajar en Visual Studio a la vez.

Limpiar su experimento

Si está desarrollando varias extensiones o simplemente explorando resultados con distintas versiones de su código de extensión, su entorno experimental puede dejar de funcionar. En este caso, debería ejecutar el script de restablecimiento.

Este script se llama Reset the Visual Studio 2013 Experimental Instance, y se proporciona como parte del SDK de Visual Studio 2013. El script quita todas las referencias a sus extensiones desde el entorno experimental para que pueda empezar desde cero. Puede ir hasta este script de dos formas:

  • Desde el Escritorio, busque Reset the Visual Studio 2013 Experimental Instance
  • Desde la línea de comandos, ejecute lo siguiente:
<VSSDK installation>\VisualStudioIntegration\Tools\Bin\
        CreateExpInstance.exe /Reset /VSInstance=12.0 
       /RootSuffix=Exp && PAUSE

Implementar la extensión

AHora que su extensión funciona como debería, es el momento de pensar en compartirla con sus amigos y compañeros. Es fácil, siempre que tenga Visual Studio 2013 instalado. Todo lo que tiene que hacer es enviarles el archivo .vsix que ha compilado. Asegúrese de compilarlo en modo Release.

Puede encontrar el archivo .vsix de esta extensión en el directorio bin de StartNotepad. Asumiendo que ha compilado la configuración Release, estará en \D:\Code\StartNotepad\StartNotepad\bin\Release\StartNotepad.vsix.

Para instalar la extensión, el usuario debe cerrar todas las instancias abiertas de Visual Studio y hacer doble clic en el archivo .vsix para traer el instalador de VSIX. Los archivos se copiarán en el directorio %LocalAppData%\­Microsoft\VisualStudio\12.0\Extensions.

Cuando el usuario vuelva a Visual Studio, encontrará la extensión StartNotepad en Herramientas | Extensiones y actualizaciones. Podrá ir a Extensiones y actualizaciones para desinstalar o deshabilitar la extensión.

Aprender a crear extensiones le permite personalizar por completo su experiencia de Visual Studio. También le permite compartir sus mejores características y actualizaciones de productividad con la comunidad. A Microsoft también le encanta que publique sus extensiones.

Resumen

Este artículo ha descrito solo una pequeña parte de lo que puede hacer con extensiones de Visual Studio. Para más información sobre las extensiones de Visual en general, vea la página “Integrate Your App or Service with Visual Studio”, en bit.ly/1zoIt59 (en inglés).

Para una vista en mayor profundidad, vea los artículos de la MSDN Library en la sección “Extending Visual Studio Overview” de bit.ly/1xWoA4k (en inglés). Y, para ver algunos buenos ejemplos de códigos para usarlos cuando desee poner en práctica sus conocimientos, consulte la colección de muestras en la galería de ejemplos de MSDN, en bit.ly/1xWp5eD. Cuando haya compilado y compartido unas cuantas extensiones, podrá personalizar de verdad su entorno de Visual Studio.


Susan Norwood ha trabajado en Microsoft, en su mayor parte escribiendo sobre el SDK de Visual Studio. Ha ayudado a muchas personas a integrar sus herramientas en Visual Studio.

Doug Erickson lleva 13 años trabajando como desarrollador y redactor técnico en Microsoft. Ve con alegría lo que los desarrolladores hacen con la Comunidad de Visual Studio para desarrollar aplicaciones y juegos para todas las plataformas.

Gracias a los siguientes expertos técnicos de Microsoft por revisar este artículo: Anthony Cangialosi y Ryan Molden