Uso del SDK de extensibilidad de VisualStudio.Extensibility y VSSDK juntos

Aunque el modelo de extensibilidad de VisualStudio.Extensibility se creó principalmente para hospedar extensiones fuera del proceso de devenv.exe, es posible usar las API del SDK de Extensibilidad de VisualStudio.Extensibility en una extensión que se ejecuta en el proceso de Visual Studio y usar las API de extensibilidad tradicionales proporcionadas por los paquetes Microsoft.VisualStudio.Sdk .

La compatibilidad con el uso en proceso está pensada para permitir que los usuarios pioneros puedan usar las nuevas API de extensibilidad de VisualStudio.Extensibility mientras se basa en Microsoft.VisualStudio.Sdk para cubrir cualquier brecha de características.

Este documento es un tutorial rápido sobre diferentes opciones para usar el SDK de extensibilidad de VisualStudio.Extensibility en proceso.

  • Si va a desarrollar una nueva extensión, nuestro método recomendado es crear una extensión visualStudio.Extension hospedada en proceso siguiendo este tutorial. Este método permite usar funcionalidades completas del SDK de extensibilidad de VisualStudio.Extensibility además de poder insertar servicios VSSDK y MEF.

  • Si tiene una extensión VSSDK existente, puede seguir estas sugerencias para usar la nueva instancia de VisualStudioExtensibility en la extensión.

  • Si desea agregar comandos, visualizadores de depuración, ventanas de herramientas a la extensión VSSDK existente mediante el SDK de extensibilidad de VisualStudio.Extensibility, puede hacer referencia a estas sugerencias para hospedar una extensión VSSDK y una extensión visualStudio.Extensibility en el mismo proyecto de extensión de VS.

Creación de la primera extensión VisualStudio.Extensibility compatible con VSSDK

Aunque el modelo de extensibilidad de VisualStudio.Extensibility se creó principalmente para hospedar extensiones fuera del proceso de devenv.exe, a partir de Visual Studio 2022 17.4 Preview 1, es posible crear una extensión de extensibilidad de VisualStudio.Extensibility hospedada en devenv.exe y puede usar las API de extensibilidad tradicionales proporcionadas por los paquetes Microsoft.VisualStudio.Sdk .

Requisitos previos

  • Visual Studio 2022, versión preliminar 17.9, o posterior, con la Visual Studio extension development carga de trabajo.
  • Si va a actualizar desde compilaciones anteriores, asegúrese de desinstalar VisualStudio.Extensibility Project System para evitar posibles conflictos.

Creación del proyecto de extensión

  • Use la extensión de extensibilidad de VisualStudio.Extensibility con la plantilla compatibilidad del SDK de VS para crear una nueva solución.

Screenshot of the VisualStudio.Extensibility in-process extension project template.

Depuración de la extensión

  • Establezca el proyecto contenedor como Proyecto de inicio, presione F5 para iniciar la depuración.

  • Al presionar se compila F5 la extensión e se implementa en la instancia experimental de la versión de Visual Studio que usa. El depurador debe adjuntar una vez cargada la extensión.

  • Puede encontrar el comando en Extensions el menú, como se muestra en la siguiente imagen:

    Screenshot showing sample extension command.

Consumo de servicios del SDK de Visual Studio desde una extensión de extensibilidad de VisualStudio.Extensibility

Un proyecto de extensión compatible con VS-SDK hace referencia al paquete Microsoft.VisualStudio.Sdk , que permite el acceso a todos los servicios del SDK de Visual Studio.

Tradicionalmente, estos servicios se consumen a través de MEF o AsyncServiceProvider. En su lugar, se recomienda un extensor de extensibilidad de VisualStudio.Extensibility a la inserción de dependencias de .NET.

Las MefInjection<TService> clases y AsyncServiceProviderInjection<TService, TInterface> (tanto del Microsoft.VisualStudio.Extensibility.VSSdkCompatibility espacio de nombres) permiten consumir los servicios del SDK de Visual Studio agregándolos al constructor de una clase que se crea una instancia a través de la inserción de dependencias (como un comando, una ventana de herramientas o un elemento de extensión).

En el ejemplo siguiente se muestra cómo se pueden agregar los DTE2 servicios y IBufferTagAggregatorFactoryService a un comando .

    [VisualStudioContribution]
    public class Command1 : Command
    {
        private TraceSource traceSource;
        private AsyncServiceProviderInjection<DTE, DTE2> dte;
        private MefInjection<IBufferTagAggregatorFactoryService> bufferTagAggregatorFactoryService;

        public Command1(
            VisualStudioExtensibility extensibility,
            TraceSource traceSource,
            AsyncServiceProviderInjection<DTE, DTE2> dte,
            MefInjection<IBufferTagAggregatorFactoryService> bufferTagAggregatorFactoryService)
            : base(extensibility)
        {
            this.dte = dte;
            this.bufferTagAggregatorFactoryService = bufferTagAggregatorFactoryService;
        }
    
        public override CommandConfiguration CommandConfiguration => new("Sample Remote Command")
        {
            Placements = new[] { CommandPlacement.KnownPlacements.ExtensionsMenu },
            Icon = new(ImageMoniker.KnownValues.Extension, IconSettings.IconAndText),
        };

Anatomía de una extensión de extensibilidad compatible con VSSDK

Aunque el uso de la plantilla de compatibilidad de VisualStudio.Extensibility con VS SDK se encarga de configurar toda la solución, resulta útil saber cuáles son los componentes básicos de una extensión visualStudio.Extensibility compatible con VS-SDK y cómo difiere de la variante común descrita en la guía "Crear su primera extensión".

Proyecto de contenedor

Una solución de extensibilidad de VisualStudio.Extensibility compatible con VS-SDK se compone de dos proyectos:

  1. una biblioteca de clases que hace referencia tanto a los paquetes de VisualStudio.Extensibility como al SDK de Visual Studio y contiene todo el código de la extensión,
  2. un proyecto VSIX de contenedor que se usa para implementar y depurar la extensión.

Esta separación es una solución temporal mientras visualStudio.Extensibility está en versión preliminar y se está finalizando el diseño final de empaquetado e implementación.

El extensor no debe agregar código, contenido ni recursos al proyecto de contenedor. El único objetivo del proyecto de contenedor es incluir los recursos proporcionados por el otro proyecto.

TargetFramework

Tanto el proyecto de extensión como el proyecto de contenedor deben tener como destino la versión de .NET que usa la versión de Visual Studio de destino. Para Visual Studio 2022, deben tener como destino .NET Framework 4.7.2.

Propiedad RequireInProcessHosting

La Extension clase debe configurarse con la RequiresInProcessHosting = true propiedad que identifica la extensión como en proceso.

[VisualStudioContribution]
internal class MyExtension : Extension
{
    public override ExtensionConfiguration? ExtensionConfiguration => new()
    {
        RequiresInProcessHosting = true,
    };

    ...

Uso de VisualStudio.Extensibility de las extensiones de VSSDK existentes

Para las extensiones de VSSDK existentes, otra opción es consultar la instancia de VisualStudioExtensibility a través del proveedor de servicios y usar sus métodos. Este método permite usar el nuevo área expuesta de API del SDK de extensibilidad de VisualStudio.Extensibility en los componentes existentes. Esta opción puede ser útil en situaciones en las que le gusta usar la nueva API para consultar la información del proyecto, la administración de documentos sin crear una nueva extensión basada en la extensibilidad de VisualStudio.Extensibility.

Este es un fragmento de código de ejemplo que muestra cómo se puede usar VisualStudioExtensibility en un paquete VSSDK:

  • En el .csproj archivo, incluya una referencia de paquete a las API de extensibilidad de VisualStudio.Extensibility:
  <ItemGroup>
    <PackageReference Include="Microsoft.VisualStudio.Extensibility" Version="17.9.23-preview-1" />
  </ItemGroup>
...
using Microsoft.VisualStudio.Extensibility;
...

public class VSSDKPackage : AsyncPackage
{
    protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
    {
        VisualStudioExtensibility extensibility = await this.GetServiceAsync<VisualStudioExtensibility, VisualStudioExtensibility>();
        await extensibility.Shell().ShowPromptAsync("Hello from in-proc", PromptOptions.OK, cancellationToken);
        ...
    }
}

Agregar una extensión de extensibilidad de VisualStudio.Extensibility a un proyecto de extensión VSSDK existente

Si también desea contribuir a componentes como ventanas de herramientas, agentes de escucha del editor mediante el SDK de extensibilidad de VisualStudio.Extensibility dentro de la extensión VSSDK existente, tendrá que seguir pasos adicionales para crear una instancia de extensión de extensibilidad de VisualStudio.Extensibility en el proyecto.

  • Necesita un estilo .csproj de SDK para usar los paquetes del SDK de extensibilidad de VisualStudio.Extensibility. En el caso de los proyectos existentes, es posible que deba actualizarlo .csproj a un estilo de SDK uno.

  • Quite la referencia de paquete para Microsoft.VSSDK.BuildTools y agregue en su lugar referencias de paquete para VisualStudio.Extensibility.

    <PackageReference Include="Microsoft.VisualStudio.Extensibility.Sdk" Version="17.9.23-preview-1" />
    <PackageReference Include="Microsoft.VisualStudio.Extensibility.Build" Version="17.9.23-preview-1" />
  • Agregue VssdkCompatibleExtension la propiedad al archivo del proyecto y estabúzela en true. Esta propiedad habilitará algunas características de VSSDK para la compatibilidad.
<PropertyGroup>
    <VssdkCompatibleExtension>true</VssdkCompatibleExtension>
</PropertyGroup>    

Ahora puede usar todas las funcionalidades de VisualStudio.Extensibility junto con la extensión VSSDK existente.