Agosto de 2017
Volumen 32, número 8
Visual Studio: crear extensiones para varias versiones de Visual Studio
Por Carlos Quintero | Agosto de 2017
La publicación de una nueva versión de Visual Studio es siempre un desafío para los desarrolladores de extensiones (paquetes, complementos, plantillas, etc.). Por ejemplo, Visual Studio 2010 presentó la nueva unidad de implementación Visual Studio Installer for eXtensions (archivos VSIX); Visual Studio 2012 presentó los temas claro/oscuro; y Visual Studio 2015 quitó complementos (con el Administrador de complementos); por no mencionar que cada versión de Visual Studio proporciona un nuevo SDK, nuevos ensamblados de extensibilidad y nuevas API. Con Visual Studio 2017, este desafío es incluso mayor, debido a la nueva instalación modular basada en cargas de trabajo y componentes individuales, y a una nueva versión del manifiesto para el mecanismo de implementación de VSIX. Aunque algunos desarrolladores (donde se destacan los de Microsoft) publican una nueva extensión diferente para cada versión de Visual Studio, la mayoría preferiría publicar una única extensión actualizada que pudiera dirigirse a la mayor variedad de versiones de Visual Studio.
En este artículo, se explicará cómo hacerlo. A tales efectos, voy a centrarme en el escenario más común: un paquete con un comando, creado en un lenguaje administrado (en este caso, C#) e implementado como archivo VSIX.
Los objetivos que deben cumplirse son los siguientes:
- Usar un único proyecto de Visual Studio para crear el paquete.
- Usar Visual Studio 2017 para el desarrollo y la depuración.
- Generar un único archivo DLL del paquete como resultado de la compilación.
- Colocar ese único archivo DLL dentro de un solo archivo VSIX.
- Poder instalar ese archivo VSIX en Visual Studio 2017 y en muchas versiones anteriores (2015, 2013, etc.).
Dado que se necesitan dos artefactos (un archivo DLL, que es el paquete, y un archivo VSIX, que es el vehículo de implementación del paquete), voy a explicar cada uno por separado: en primer lugar, cómo funcionan en la instalación en tiempo de ejecución y, en segundo lugar, cómo desarrollarlos.
El archivo VSIX
Como se ha mencionado, Visual Studio 2010 presentó el mecanismo de implementación VSIX para instalar las extensiones de Visual Studio y ha sido el método preferido desde entonces. Un archivo VSIX tiene la extensión .vsix y puede instalarse de varias maneras. Si el archivo VSIX se publica en Visual Studio Marketplace (antiguamente, Galería de Visual Studio) y es compatible con la versión y edición de Visual Studio que usa, puede instalarlo desde el cuadro de diálogo Extensiones y actualizaciones. En el menú Herramientas, haga clic en Extensiones y actualizaciones y luego vaya a En línea | Visual Studio Marketplace (consulte la Figura 1: ventana del cuadro de diálogo Extensiones y actualizaciones).
Figura 1: Ventana del cuadro de diálogo Extensiones y actualizaciones
También puede hacer doble clic en un archivo VSIX. Cuando esto sucede, se ejecuta un iniciador de Visual Studio (C:\Archivos de programa (x86)\Archivos comunes\Microsoft Shared\MSEnv\VSLauncher.exe) asociado con la extensión de archivo .vsix; esto ubica la utilidad VSIXInstaller.exe de la versión superior de Visual Studio instalada (se necesita la versión superior para poderlo instalar en todas las versiones inferiores). Luego, el Instalador de VSIX muestra el cuadro de diálogo en la Figura 2: Instalador de VSIX, para que pueda seleccionar las versiones y ediciones de Visual Studio compatibles en las que quiere instalar la extensión.
Figura 2: Instalador de VSIX
Además, los archivos VSIX pueden instalarse mediante programación usando la utilidad VSIXInstaller.exe con las opciones de la línea de comandos, como la versión (2017, 2015, etc.) y la edición (Community, Professional, etc.) de Visual Studio de destino. Esa utilidad puede encontrarse en la subcarpeta Common7\IDE de la instalación de Visual Studio.
En todo caso, Visual Studio o la utilidad VSIXInstaller.exe deben saber qué versiones y ediciones de Visual Studio admite el archivo VSIX. Esa información puede conocerse a través de un archivo de manifiesto dentro del archivo. El archivo VSIX en realidad es un archivo .zip, por lo que puede cambiar la extensión .vsix del archivo a .zip y luego abrirlo para examinar el contenido (consulte la Figura 3: contenido de un archivo VSIX).
Figura 3: Contenido de un archivo VSIX
Como puede ver, hay varios archivos dentro: El archivo .dll es el DLL del paquete. El archivo .pkgdef se usa en el momento de la instalación para agregar algunas claves al Registro de Windows que permiten que Visual Studio reconozca el DLL como paquete. El archivo [Content_Types].xml describe el tipo de contenido de cada extensión de archivo (.dll, .json, etc.). Los archivos catalog.json y manifest.json son los requeridos por Visual Studio 2017. Asimismo, el archivo extension.vsixmanifest describe el nombre de la extensión, la versión, etc., y qué versiones y ediciones de Visual Studio admite.
Puede descomprimir el archivo extension.vsixmanifest y abrirlo con un editor de texto para examinar el contenido, que se verá similar a lo que se muestra en la Figura 4: contenido de un archivo de manifiesto.
Figura 4: Contenido de un archivo de manifiesto
Como verá, el manifiesto indica las ediciones de Visual Studio compatibles en el elemento XML InstallationTarget. Aquí, el valor Microsoft.VisualStudio.Pro está dirigido a la edición Professional y superior, como las ediciones Premium, Ultimate, Enterprise y demás. Tenga en cuenta que también está dirigida a la edición Community, que es básicamente una edición Professional con algunas restricciones de licencias y sin algunas características. También indica la variedad de versiones compatibles de Visual Studio: 10.0 (2010), 11.0 (2012), 12.0 (2013), 14.0 (2015), 15.0 (2017).
Cuando se instala el archivo VSIX de una extensión por usuario (ya sea mediante Visual Studio o por el instalador de VSIX), los archivos en el interior se descomprimen y copian en una carpeta aleatoria en esta ubicación: C:\Usuarios\<usuario>\AppData\Local\Microsoft\VisualStudio\<número de versión>\Extensions\<carpeta aleatoria>. El <número de versión> puede tener un sufijo “Exp” adjunto para la “instancia experimental” (se explica más adelante) y, para Visual Studio 2017, también incluirá el “id. de instancia” de la instalación de Visual Studio. Este id. de instancia se genera al azar durante la instalación de Visual Studio; se agregó para admitir las instalaciones en paralelo de distintas ediciones de la misma versión (2017) de Visual Studio, algo que antes no era posible. Para extensiones de nivel de máquina, se usa la subcarpeta Common7\IDE\Extensions. Tenga en cuenta que, en todo caso, cada versión de Visual Studio usa su propia carpeta para las extensiones.
Si bien sería conveniente que todas las versiones de Visual Studio admitieran el mismo formato de manifiesto, lamentablemente no es así. Visual Studio 2010 introdujo VSIX y la primera versión del manifiesto. Visual Studio 2012 introdujo la versión 2, que es totalmente diferente e incompatible con la versión 1. Sin embargo, Visual Studio 2012, 2013 y 2015 (todos ellos admiten la versión 2) aún aceptan un manifiesto de la versión 1, por lo que puede compilar un archivo VSIX con una versión 1 y usarlo para Visual Studio 2010 hasta 2015. Pero Visual Studio 2017 no admite ni la versión 1 ni la versión 2. En su lugar, requiere una tercera versión del manifiesto. Afortunadamente, la versión 3 sigue usando el valor “2.0.0.0” en el atributo Version del elemento XML PackageManifest y se agrega solo un elemento XML denominado <Prerequisites> (y los dos nuevos archivos, catalog.json y manifest.json, al archivo VSIX). Entonces, es totalmente compatible con la segunda versión, admitida por Visual Studio 2012, 2013 y 2015 (pero no por Visual Studio 2010, que solo admite la versión 1). Es decir, no puede dirigirse a Visual Studio 2010-2017 con un único archivo VSIX. Desde este punto, voy a dejar de lado Visual Studio 2010 y continuaré con un archivo VSIX que admita Visual Studio 2012, 2013, 2015 y 2017.
DLL del paquete
Un paquete administrado de Visual Studio es un DLL que contiene una clase que se hereda de Microsoft.VisualStudio.Shell.Package. Está decorado con ciertos atributos que, durante la compilación, ayudan a generar un archivo .pkgdef (que, como se menciona antes, se encuentra en el archivo VSIX y en la carpeta de instalación de la extensión). El archivo .pkgdef se usa en el arranque (versiones más antiguas de Visual Studio) o durante la instalación (versión 15.3 de Visual Studio 2017) para registrar el archivo DLL como paquete de Visual Studio. Una vez que esté registrado, Visual Studio intentará cargar el paquete en algún momento, ya sea en el arranque o cuando se ejecute uno de sus comandos si el paquete usa la carga de retraso (que es el procedimiento recomendado). Durante el intento de cargar el archivo DLL administrado e inicializar el paquete, suceden tres cosas: Common Language Runtime (CLR) de una versión de Microsoft .NET Framework cargará el DLL; este usará algunos archivos DLL proporcionados por una instancia de .NET Framework; y usará algunos archivos DLL proporcionados por Visual Studio. Analizaré cada uno de estas situaciones en orden.
.NET Framework es la suma de dos cosas: CLR y bibliotecas (tanto bibliotecas de clase base como adicionales). CLR es el runtime (el compilador JIT, el recolector de elementos no utilizados, etc.) y carga los archivos DLL administrados. En un pasado remoto, .NET Framework de las versiones 1.0, 1.1 y 2.0 (usadas por Visual Studio.NET 2002, Visual Studio.NET 2003 y Visual Studio 2005) proporcionaba su propia versión de CLR (1.0, 1.1 y 2.0). No obstante, .NET Framework 3.0 y 3.5, que se usaban en Visual Studio 2008, siguieron usando exactamente el mismo CLR 2.0 que .NET Framework 2.0, en lugar de presentar uno nuevo. Visual Studio 2010 introdujo .NET Framework 4 y CLR 4.0, pero, desde entonces, todas las nuevas versiones de .NET Framework 4.x han usado CLR 4.0 (aunque cambiándolo “en contexto” con una versión compatible con versiones anteriores, en lugar de reutilizar el mismo CLR 4.0 de .NET Framework 4). Dado que Visual Studio 2012 y todas las versiones superiores usan CLR 4.0, la versión de CLR no es un problema cuando el DLL de una extensión se dirige a Visual Studio 2012, 2013, 2015 y 2017.
Las bibliotecas constituyen la segunda parte de .NET Framework; estas son DLL referenciadas por un proyecto de Visual Studio y utilizadas en tiempo de ejecución. Para desarrollar una única extensión que se dirija a varias versiones de Visual Studio, debe usar la versión superior de .NET Framework instalada de manera predeterminada por la versión menor de Visual Studio a la que quiere dirigirse. Es decir, si quiere dirigirse a Visual Studio 2012 y superior, debe usar .NET Framework 4.5. No puede usar, por ejemplo, .NET Framework 4.5.1, que se introdujo en Visual Studio 2013, ya que en un equipo que solo tenga instalado Visual Studio 2012 no habría ningún DLL introducido en aquella versión. A menos que en verdad necesite ese DLL, no querrá obligar a los usuarios a instalar .NET Framework 4.5.1 para que usen su extensión (esto podría afectar a las ventas o las descargas y el soporte técnico).
La extensión también necesita DLL que proporcione Visual Studio (en general, denominados Microsoft.VisualStudio.*). En tiempo de ejecución, Visual Studio encuentra los archivos DLL en ubicaciones conocidas, como la carpeta Common7\IDE con las subcarpetas Common7\IDE\PublicAssemblies y Common7\IDE\PrivateAssemblies, y en la caché global de ensamblados (GAC). La GAC para .NET Framework 4.x se encuentra en C:\Windows\Microsoft.NET\assembly (hay otra GAC en C:\Windows\assembly, pero esa es para versiones más antiguas de .NET Framework). Visual Studio 2017 usa una instalación más aislada, que evita la GAC y, en su lugar, se basa en las carpetas descritas anteriormente.
Hay un par de principios clave que debe seguir al desarrollar y generar un archivo VSIX: debe usar las versiones proporcionadas por la versión más antigua de Visual Studio a la que se dirija su extensión. Esto significa que, si quiere dirigirse a Visual Studio 2012 y superior, debe usar solo ensamblados y API de extensibilidad proporcionados por esa versión (o inferior). Si la extensión usa un DLL introducido por Visual Studio 2013 o superior, la extensión no funcionará en una máquina que solo tenga Visual Studio 2012. El segundo principio es que la extensión nunca debe implementar DLL de Visual Studio, ni en las ubicaciones mencionadas (las carpetas de Visual Studio y la GAC), ni en la carpeta de instalación de la extensión. La versión de destino de Visual Studio proporciona estos DLL, por lo que el archivo VSIX no debería incluirlos.
Muchos DLL de Visual Studio incluyen un número de versión (8.0… 15.0) en el nombre, por ejemplo: Microsoft.VisualStudio.Shell.11.0.dll o Microsoft.VisualStudio.Shell.Immutable.10.0.dll. Esto ayuda a identificar la versión de Visual Studio que los introdujo, pero no se engañe: es un nombre, no una versión. Por ejemplo, hay cuatro versiones (11.0.0.0, 12.0.0.0, 14.0.0.0 y 15.0.0.0) de Microsoft.Visual.Studio.Shell.11.0.dll, cada una proporcionada, respectivamente, por una versión de Visual Studio (2012, 2013, 2015 y 2017). Las primeras tres, de 11.0.0.0 a 14.0.0.0, se instalan con la versión correspondiente de Visual Studio en la GAC, y la cuarta versión, 15.0.0.0, usada por Visual Studio 2017, se instala en la carpeta Common\IDE\PrivateAssemblies.
Dado que una extensión que se dirige a Visual Studio 2012 y superior debe usar ensamblados de Visual Studio con la versión 11.0.0.0 (el primer principio mencionado anteriormente), esto hace que Microsoft.Visual.Studio.Shell.11.0.dll de referencia deba ser la versión 11.0.0.0. Pero, como Visual Studio 2013 y las versiones superiores no instalan esa versión (comienzan por la versión 12.0.0.0), y la extensión no debería implementar DLL de Visual Studio (el segundo principio), ¿no se produciría un error de la extensión al intentar usar ese DLL de Visual Studio? La respuesta es “no” y es gracias a un mecanismo de redireccionamiento de enlace de ensamblados que proporciona .NET Framework, que permite especificar reglas como esta: “cuando algo solicita esta versión de un ensamblado, usar esta versión más nueva“. Claro que la versión nueva debe ser totalmente compatible con la versión anterior. Hay varias maneras de redirigir ensamblados de una versión a otra. Esta es una manera: Un ejecutable (extensión de archivo .exe) puede proporcionar un archivo de configuración adjunto (extensión de archivo .exe.config) que especifique las redirecciones. Entonces, si va a la carpeta Common7\IDE de la instalación de Visual Studio, encontrará el ejecutable devenv.exe de Visual Studio y un archivo devenv.exe.config. Si abre el archivo .config con un editor de texto, verá que contiene muchas redirecciones de ensamblados:
<dependentAssembly>
<assemblyIdentity
name="Microsoft.VisualStudio.Shell.11.0"
publicKeyToken="b03f5f7f11d50a3a"
culture="neutral"/>
<bindingRedirect
oldVersion="2.0.0.0-14.0.0.0
newVersion="15.0.0.0"/>
</dependentAssembly>
Por tanto, Visual Studio 2017 (15.0) tiene una redirección de la versión del ensamblado para Microsoft.VisualStudio.Shell.11.0 que indica que cada vez que algo solicite versiones anteriores, de 2.0.0.0 a 14.0.0.0, use la nueva versión 15.0.0.0 en su lugar. Así es como Visual Studio 2013 o superior pueden usar una extensión que hace referencia a Microsoft.VisualStudio.Shell.11.0 versión 11.0.0.0, incluso aunque no proporcionen esa versión específica.
Desarrollar la extensión
Ahora que sabe cómo funciona todo en tiempo de ejecución, puede desarrollar el paquete. Para recapitular, creará un proyecto de VSIX con Visual Studio 2017 con un manifiesto que se dirija a las versiones de 12.0 a 15.0 de Visual Studio; contendrá un paquete y un comando; y usará solo referencias con la versión 11.0.0.0 (o inferior) instalada por Visual Studio 2012.
En este momento, podría preguntarse qué versiones de Visual Studio deben instalarse en la máquina de desarrollo. El procedimiento recomendado es tener dos máquinas de desarrollo según se indica a continuación: En la primera, si tiene suficiente espacio en el disco, instale todas las versiones de Visual Studio: 2012, 2013, 2015 y 2017. Todas pueden coexistir en paralelo, y podrá probarlas durante el desarrollo. Para Visual Studio 2017, distintas ediciones, como Community, Professional y Enterprise, pueden coexistir a la vez, algo que no era posible en las versiones anteriores de Visual Studio. Si el espacio disponible es un problema, instale los componentes mínimos para las versiones antiguas, u omita alguna versión del medio (2013 o 2015).
En la segunda máquina de desarrollo, instale solo Visual Studio 2017 o, aún mejor, un servidor de compilación sin ninguna versión de Visual Studio instalada (solo Build Tools 2017) para compilar la extensión para la publicación. Este enfoque le permitirá asegurarse de que no usa por accidente los archivos DLL u otras dependencias de carpetas instaladas por versiones anteriores de Visual Studio. También puede que se pregunte si no sería más seguro desarrollar o compilar en una máquina solo con Visual Studio 2012 instalado y la respuesta es que esto no es posible: Para generar un archivo VSIX para Visual Studio 2017 (que crea un manifiesto de versión 3 y agrega los archivos catalog.json y manifest.json), necesita Visual Studio SDK 15.0 de Visual Studio 2017 o, con algo de trabajo, Visual Studio SDK 14.0 de Visual Studio 2015. Ni Visual Studio SDK 12.0 de Visual Studio 2013 ni Visual Studio SDK 11.0 de Visual Studio 2012 pueden generar archivos VSIX para Visual Studio 2017.
Y el procedimiento recomendado para pruebas (en serio) es: Use otra máquina (virtual o basada en la nube) para cada versión de Visual Studio (por lo que necesitará cuatro máquinas para probar la extensión en Visual Studio 2012 a Visual Studio 2017 por separado). Este procedimiento recomendado me ayudó a encontrar algunos errores en el código de ejemplo para este artículo.
Para obtener las plantillas del proyecto de Visual Studio 2017 para crear un paquete (o cualquier otro tipo de extensión), necesita la carga de trabajo “Desarrollo de extensiones de Visual Studio”. Si no la instaló cuando instaló Visual Studio 2017 por primera vez, vaya a la carpeta C:\Archivos de programa (x86)\Microsoft Visual Studio\Installer, inicie vs_Installer.exe, haga clic en el botón Modificar y seleccione esa carga de trabajo al final de la lista.
Cree un nuevo proyecto de VSIX con el menú Archivo | Nuevo | Proyecto; vaya a Visual C# | Extensibility templates (Plantillas de extensibilidad); asegúrese de haber seleccionado .NET Framework 4.5 en la lista desplegable de la parte superior y seleccione la plantilla VSIX Project. Nombre el proyecto VSIXProjectVS2012_2017. Haga doble clic en el archivo source.extension.vsixmanifest para abrir el editor personalizado. En la pestaña Metadatos, defina el nombre del producto, el creador, la versión, etc. En la pestaña Destinos de instalación, haga clic en el botón Editar, seleccione el identificador Microsoft.VisualStudio.Pro (ese valor también se dirige a la edición Community, que es básicamente la edición Professional) y establezca el intervalo de instalación de destino, [11.0,15.0], como se muestra en la Figura 5. Un corchete recto indica que el valor está incluido. Un paréntesis indicaría que el valor está excluido, por lo que también puede establecer lo siguiente: [11.0,16.0). También puede dirigirse a una versión inferior (como 15.3) con el número de compilación (por ejemplo: 15.0.26208.1).
Figura 5: Destinos de instalación
En la pestaña Dependencias, elimine todos los elementos. En la pestaña Requisitos previos, haga clic en el botón Editar y establezca el componente mínimo de Visual Studio 2017 que requiere su extensión. En este ejemplo, solo se requiere el Editor de núcleo de Visual Studio. Esta sección es nueva para Visual Studio 2017 y el manifiesto de versión 3, por lo que solo se aplica a la versión 15.0 (consulte la Figura 6: Requisitos previos):
Figura 6: Requisitos previos
Para agregar un paquete al proyecto de VSIX, haga doble clic en el nodo del proyecto de VSIX en Explorador de soluciones y luego seleccione el menú Agregar | Nuevo elemento para abrir el cuadro de diálogo Agregar nuevo elemento. Ahora, vaya al nodo Visual Studio C# Items (Elementos de Visual Studio C#) | Extensibilidad | VSPackage, seleccione la plantilla Paquete de Visual Studio y nómbrela MyPackage.cs. Agregue un comando al paquete repitiendo las acciones del paso anterior, pero esta vez seleccione la plantilla Comando personalizado. Nómbrela MyCommand1.cs.
Para seguir el principio de usar la menor cantidad de dependencias requeridas, en el código fuente de MyPackage.cs y MyCommand1.cs quite los espacios de nombres sin usar (atenuados). Luego haga clic con el botón derecho en el nodo del proyecto de VSIX en el Explorador de soluciones y haga clic en la entrada Administrar paquetes NuGet para la solución. En la sección Instalado, desinstale todos los paquetes en el orden que se muestra aquí:
Microsoft.VisualStudio.Shell.15.0
Microsoft.VisualStudio.Shell.Framework
Microsoft.VisualStudio.CoreUtility
Microsoft.VisualStudio.Imaging
Microsoft.VisualStudio.Shell.Interop.12.0
Microsoft.VisualStudio.Shell.Interop.11.0
Microsoft.VisualStudio.Shell.Interop.10.0
Microsoft.VisualStudio.Threading
Microsoft.VisualStudio.Shell.Interop.9.0
Microsoft.VisualStudio.Shell.Interop.8.0
Microsoft.VisualStudio.TextManager.Interop.8.0
Microsoft.VisualStudio.Shell.Interop
Microsoft.VisualStudio.TextManager.Interop
Microsoft.VisualStudio.Validation
Microsoft.VisualStudio.Utilities
Microsoft.VisualStudio.OLE.Interop
(No desinstale el paquete Microsoft.VSSDK.BuildTools, que es Visual Studio SDK).
En el nodo Referencias del proyecto en el Explorador de soluciones, desinstale todas las referencias restantes (que no se adquirieron como paquetes NuGet), excepto System y System.Design. Ahora puede recompilar la solución. Obtendrá errores de compilación que se resolverán al agregar las referencias que se muestran en la Figura 7.
Figura 7: Referencias de Visual Studio 2012
Nombre del ensamblado | Versión del ensamblado | Subcarpeta de Visual Studio 2012 SDK |
Microsoft.VisualStudio.OLE.Interop | 7.1.40304.0 | v2.0 |
Microsoft.VisualStudio.Shell.Interop | 7.1.40304.0 | v2.0 |
Microsoft.VisualStudio.Shell.Interop.8.0 | 8.0.0.0 | v2.0 |
Microsoft.VisualStudio.Shell.Interop.9.0 | 9.0.0.0 | v2.0 |
Microsoft.VisualStudio.Shell.Interop.10.0 | 10.0.0.0 | v2.0 |
Microsoft.VisualStudio.Shell.Immutable.10.0 | 10.0.0.0 | v4.0 |
Microsoft.VisualStudio.Shell.11.0 | 11.0.0.0 | v4.0 |
Lamentablemente, Microsoft no ofrece ningún paquete NuGet oficial para Microsoft.VisualStudio.Shell.11.0 (aunque puede encontrar un paquete NuGet VSSDK.Shell.11 no oficial). Si tiene instalado Visual Studio 2012 (debería ver si es la versión mínima compatible de su extensión), puede obtenerlo de la GAC, como se explicó antes. De lo contrario, puede instalar Visual Studio 2012 SDK (bit.ly/2rnGsfq) para obtener todos los ensamblados necesarios de las subcarpetas v2.0 y v4.0 de la carpeta C:\Archivos de programa (x86)\Microsoft Visual Studio 11.0\VSSDK\VisualStudioIntegration\Common\Assemblies. La última columna de la tabla muestra la subcarpeta de Visual Studio 2012 SDK donde puede encontrar cada ensamblado.
Para evitar dependencias de paquetes NuGet no oficiales o de carpetas locales específicas (de Visual Studio SDK o de una instalación de Visual Studio), lo mejor es obtener los ensamblados desde cualquier lugar y crear una carpeta llamada VS2012Assemblies en la carpeta raíz del proyecto. Luego, copie los archivos DLL a esa carpeta, haga referencia a ellos desde allí (con el botón Examinar del cuadro de diálogo Administrador de referencias del proyecto) y agregue la carpeta VS2012Assemblies al control del código fuente, asegurándose de que los DLL se agreguen allí (normalmente, las herramientas de control del código fuente no agregan DLL de manera predeterminada). Entonces, desde este punto, los ensamblados requeridos de Visual Studio forman parte del código fuente.
Para seguir el principio de no incluir referencias a ensamblados en el archivo VSIX y ni siquiera en la carpeta de salida, seleccione cada referencia y, en la ventana Propiedades, asegúrese de que la propiedad Copia local esté definida en Falso. En este punto, la solución puede recompilarse sin errores. En el Explorador de Windows, vaya a la carpeta de salida. Solo deberían generarse estos archivos: extension.vsixmanifest, VSIXProjectVS2012_2017.dll, VSIXProjectVS2012_2017.pkgdef y VSIXProjectVS2012_2017.vsix.
Al compilar el proyecto, uno de los destinos MSBuild implementa la extensión en la Instancia experimental de Visual Studio. Esta es una instancia de Visual Studio que usa distintas carpetas y entradas del registro que la instancia normal, de modo que no deja inutilizable la instancia normal en caso de que algo salga mal con la extensión durante el desarrollo. (Siempre puede restablecer la instancia experimental; para ello, haga clic en el botón Inicio de Windows, escriba “Restablecer la” y ejecute el comando “Restablecer la instancia experimental de Visual Studio 2017”). Si va a la pestaña Depurar de la página Propiedades del proyecto, puede establecer el campo Programa externo de inicio en el archivo denenv.exe de Visual Studio 2017. (Es importante cambiar esto si actualiza, ya que apuntaría a una versión anterior de Visual Studio). También puede ver que los argumentos de la línea de comandos especifican “Exp” como sufijo de la raíz (consulte la figura 8: depurar la instancia experimental), para que también se use la instancia experimental para la depuración.
Figura 8: Depurar la instancia experimental
Haga clic en la entrada de menú Depurar | Iniciar depuración y se iniciará una nueva instancia de Visual Studio (observe que la leyenda indique “Instancia experimental”). Si hace clic en la entrada de menú Herramientas | Invoke MyCommand1 (Invocar MyCommand1), se cargará el paquete, se ejecutará el comando y aparecerá un cuadro de mensaje.
Si quiere usar Visual Studio 2017 para depurar la extensión en una versión anterior de Visual Studio, debe realizar dos cambios: en primer lugar, dado que, una vez que la extensión está compilada, esta se implementa en la Instancia experimental de Visual Studio de la versión cuyo SDK se haya usado para compilar el proyecto, debe quitar el paquete NuGet Microsoft.VSSDK.BuildTools versión 15.0 y usar la versión 14.0 para Visual Studio 2015 o la versión 12.0 para Visual Studio 2013. Para Visual Studio 2012, no hay un paquete NuGet para el VSDK, por lo que debe editar el archivo .csproj y apuntar la variable VSToolsPath a la ubicación del VSSDK 11.0 (C:\Archivos de programa (x86)\MSBuild\Microsoft\VisualStudio\v11.0), que debe instalar por separado. En segundo lugar, debe ir a la pestaña Depurar de la página Propiedades del proyecto y establecer el campo Programa externo de inicio en el ejecutable coincidente Common7\IDE\devenv.exe.
Como probablemente ya sabe, muchos proyectos de Visual Studio admiten el recorrido de ida y vuelta. Es decir, pueden abrirse y depurarse en varias versiones de Visual Studio sin sufrir modificaciones. No sucede lo mismo con los proyectos de extensibilidad “de fábrica”. Sin embargo, con cierto dominio de MSBuild y Visual Studio SDK, puede lograrlo, aunque siempre resulta ser un enfoque complicado.
Una vez que haya terminado con el desarrollo y la depuración, puede compilar la extensión en Release configuration (Configuración de versión) y probarla en las versiones instaladas de Visual Studio en instancias aisladas en las máquinas de prueba. Si todo va bien, puede publicar la extensión en Visual Studio Marketplace.
Carlos Quintero* ha recibido el premio Microsoft Most Valuable Professional en 14 ocasiones, actualmente en la categoría Visual Studio and Development Technologies. Ha ayudado a otros desarrolladores a crear extensiones para Visual Studio desde 2002 y escribe en blogs sobre esto desde 2006 en visualstudioextensibility.com y más recientemente comenzó a twittear sobre el tema: @VSExtensibility.*
Gracias a los siguientes expertos técnicos por revisar este artículo: Justin Clareburt, Alex Eyler y Mads Kristensen