Usando o SDK do VisualStudio.Extensibility e o VSSDK juntos

Embora o modelo VisualStudio.Extensibility tenha sido criado principalmente para hospedar extensões fora do processo devenv.exe, é possível usar as APIs do SDK do VisualStudio.Extensibility em uma extensão em execução no processo do Visual Studio e utilizando APIs de extensibilidade tradicionais fornecidas pelos pacotes Microsoft.VisualStudio.Sdk .

O suporte ao uso em processo destina-se a permitir que os primeiros usuários usem as novas APIs do VisualStudio.Extensibility enquanto dependem do Microsoft.VisualStudio.Sdk para cobrir qualquer lacuna de recursos.

Este documento é um passo a passo rápido sobre diferentes opções para utilizar o SDK do VisualStudio.Extensibility no proc.

  • Se você estiver desenvolvendo uma nova extensão, nosso método recomendado é criar um VisualStudio.Extension hospedado no processo após este tutorial. Esse método permite que você use todos os recursos do SDK do VisualStudio.Extensibility, além de poder injetar serviços VSSDK e MEF.

  • Se você tiver uma extensão VSSDK existente, poderá seguir estas dicas para usar a nova instância VisualStudioExtensibility em sua extensão.

  • Se você quiser adicionar comandos, visualizadores de depuração, janelas de ferramentas à sua extensão VSSDK existente usando o SDK do VisualStudio.Extensibility, consulte essas dicas para hospedar uma extensão VSSDK e uma extensão VisualStudio.Extensibility no mesmo projeto de extensão VS.

Criar sua primeira extensão do VisualStudio.Extensibility compatível com VSSDK

Embora o modelo VisualStudio.Extensibility tenha sido criado principalmente para hospedar extensões fora do processo devenv.exe, a partir do Visual Studio 2022 17.4 Preview 1, é possível criar uma extensão VisualStudio.Extensibility hospedada no devenv.exe e que pode usar APIs de extensibilidade tradicionais fornecidas pelos pacotes Microsoft.VisualStudio.Sdk .

Pré-requisitos

  • Visual Studio 2022 versão 17.9 Preview 1 ou superior com a Visual Studio extension development carga de trabalho.
  • Se você estiver atualizando de compilações anteriores, desinstale o VisualStudio.Extensibility Project System para evitar possíveis conflitos.

Criar o projeto de extensão

  • Use o modelo VisualStudio.Extensibility Extension with VS SDK Compatibility para criar uma nova solução.

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

Depurar sua extensão

  • Defina o projeto de contêiner como projeto de inicialização, pressione F5 para iniciar a depuração.

  • Pressionar F5 cria sua extensão e a implanta na instância experimental da versão do Visual Studio que você está usando. O depurador deve ser anexado assim que sua extensão for carregada.

  • Você pode encontrar o comando no Extensions menu como mostrado na imagem a seguir:

    Screenshot showing sample extension command.

Consumindo serviços SDK do Visual Studio de uma extensão VisualStudio.Extensibility

Um projeto de extensão compatível com VS-SDK faz referência ao pacote Microsoft.VisualStudio.Sdk , que permite acesso a todos os serviços do SDK do Visual Studio.

Tradicionalmente, esses serviços são consumidos por meio do MEF ou do AsyncServiceProvider. Em vez disso, um extensor VisualStudio.Extensibility é incentivado à injeção de dependência do .NET.

As MefInjection<TService> classes e AsyncServiceProviderInjection<TService, TInterface> (ambas do Microsoft.VisualStudio.Extensibility.VSSdkCompatibility namespace) permitem que você consuma os serviços do SDK do Visual Studio adicionando-os ao construtor de uma classe que é instanciada por meio de injeção de dependência (como um comando, janela de ferramenta ou parte de extensão).

O exemplo a seguir mostra como os DTE2 serviços e IBufferTagAggregatorFactoryService podem ser adicionados a um 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),
        };

Anatomia de uma extensão VisualStudio.Extensibility compatível com VSSDK

Embora o uso do modelo VisualStudio.Extensibility Extension with VS SDK Compatibility cuide da configuração de toda a solução, é útil saber quais são os componentes básicos de uma extensão VisualStudio.Extensibility compatível com VS-SDK e como ela difere da variante comum descrita no guia "criar sua primeira extensão".

Projeto de contêiner

Uma solução VisualStudio.Extensibility compatível com VS-SDK é composta por dois projetos:

  1. uma biblioteca de classes que faz referência aos pacotes VisualStudio.Extensibility e Visual Studio SDK e contém todo o código da extensão,
  2. um projeto VSIX de contêiner que você usa para implantar e depurar a extensão.

Essa separação é uma solução temporária enquanto o VisualStudio.Extensibility está em visualização e o empacotamento final e o design de implantação estão sendo finalizados.

O extensor não deve adicionar código, conteúdo ou recursos ao projeto de contêiner. O único objetivo do projeto de contêiner é incluir os ativos fornecidos pelo outro projeto.

TargetFramework

O projeto de extensão e o projeto de contêiner devem ter como destino a versão do .NET usada pela versão do Visual Studio de destino. Para o Visual Studio 2022, eles devem ter como destino o .NET Framework 4.7.2.

Propriedade RequiresInProcessHosting

A Extension classe deve ser configurada com a propriedade que identifica a RequiresInProcessHosting = true extensão como estando em processo.

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

    ...

Usar VisualStudio.Extensibility de extensões VSSDK existentes

Para extensões VSSDK existentes, outra opção é consultar a instância VisualStudioExtensibility via provedor de serviços e utilizar seus métodos. Esse método permite que você use a nova área de superfície da API do SDK do VisualStudio.Extensibility em seus componentes existentes. Essa opção pode ser útil em situações em que você deseja usar a nova API para consultar informações do projeto, gerenciamento de documentos sem criar uma nova extensão baseada em VisualStudio.Extensibility.

Aqui está um trecho de código de exemplo que mostra como se pode utilizar VisualStudioExtensibility dentro de um pacote VSSDK:

  • No arquivo .csproj , inclua uma referência de pacote às APIs do 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);
        ...
    }
}

Adicionar uma extensão VisualStudio.Extensibility a um projeto de extensão VSSDK existente

Se você também quiser contribuir com componentes como janelas de ferramentas, ouvintes de editor usando o SDK do VisualStudio.Extensibility dentro de sua extensão VSSDK existente, você terá que seguir etapas adicionais para criar uma instância de extensão VisualStudio.Extensibility em seu projeto.

  • Você precisa de um estilo .csproj SDK para utilizar pacotes SDK do VisualStudio.Extensibility. Para projetos existentes, talvez seja necessário atualizar para .csproj um estilo SDK.

  • Remova a referência de pacote para e, em vez disso, adicione referências de pacote para Microsoft.VSSDK.BuildTools 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" />
  • Adicione VssdkCompatibleExtension a propriedade ao arquivo de projeto, definindo-a como true. Essa propriedade habilitará alguns recursos VSSDK para compatibilidade.
<PropertyGroup>
    <VssdkCompatibleExtension>true</VssdkCompatibleExtension>
</PropertyGroup>    

Agora você pode usar todos os recursos do VisualStudio.Extensibility junto com sua extensão VSSDK existente.