Sua primeira extensão do Visual Studio

Este artigo orienta você por algumas etapas simples para colocar sua primeira extensão do Visual Studio em funcionamento. Uma extensão do Visual Studio é escrita usando o .NET Framework e C#. Se você já é um desenvolvedor .NET, descobrirá que escrever extensões é semelhante a escrever a maioria dos outros programas e bibliotecas .NET.

A extensão que vais escrever hoje adiciona um comando que insere um novo GUID no editor de texto quando executado. É simples, útil e fornece uma boa introdução aos vários aspetos do desenvolvimento da extensão.

Se você é um aprendiz visual, confira este pequeno vídeo de alguém seguindo o tutorial.

Antes de começar a escrever sua primeira extensão do Visual Studio (é fácil, prometo!), verifique se você tem as ferramentas necessárias.

Criar o projeto

Existem vários modelos de projeto para escolher, então você quer fazer a escolha certa. Os modelos usados neste kit de ferramentas da comunidade, todos têm o apelido (Comunidade) no nome.

O modelo VSIX Project w/Command (Comunidade) vem com um comando configurado, o que facilita começar a usá-lo. Este é um ótimo ponto de partida para a maioria das extensões. Se você sabe que deseja uma janela de ferramenta, use o modelo VSIX Project w/Tool Window (Community). Ele também tem um comando para abrir a janela da ferramenta.

Use os modelos Projeto VSIX vazio (Comunidade) ou Projeto VSIX (Comunidade) para extensões somente MEF ou outros cenários avançados.

Desta vez, você selecionará o modelo VSIX Project w/Command (Community), conforme mostrado na captura de tela abaixo.

Nova caixa de diálogo do projeto mostrando modelos de projeto VSIX.

Depois de selecionar o modelo de projeto, você precisa dar um nome ao seu projeto. Chame-lhe InsertGuid.

Configure seu novo projeto.

Depois de pressionar o botão Criar , você deve acabar com um projeto VSIX básico parecido com este:

Novos arquivos e pastas de projeto.

Ficheiros importantes

Vamos analisar os arquivos mais importantes.

InsertGuidPackage.cs é o que é referido como a classe Package. Seu InitializeAsync(...) método é chamado pelo Visual Studio para inicializar sua extensão. É a partir daqui que você adiciona ouvintes de eventos e registra comandos, janelas de ferramentas, configurações e outras coisas.

source.extension.vsixmanifest é o arquivo de manifesto para sua extensão. Ele contém metadados, como título e descrição, mas também informações sobre o que a extensão contém.

VSCommandTable.vsct é um arquivo XML onde comandos e associações de chave são definidos declarativamente, para que possam ser registrados com o Visual Studio.

Commands/MyCommand.cs é o manipulador de comandos para o comando definido no arquivo VSCommandTable.vsct . Ele controla o que acontece quando o comando é executado clicando no botão.

Modificando o comando

Primeiro, você deseja certificar-se de que seu comando tem o nome, ícone e posição corretos dentro do sistema de menu do Visual Studio.

Abra o arquivo VSCommandTable.vsct e localize a <Group> e a <Button>. Observe como o botão especifica o grupo como sendo seu pai e o pai do grupo é o menu VSMainMenu/Tools interno.

Para a sua extensão, pretende que o botão de comando Inserir GUID esteja sob o menu principal Editar, então vai reatribuir o grupo ao menu Editar. Substitua Ferramentas por Editar conforme mostrado no trecho a seguir:

<Group guid="InsertGuid" id="MyMenuGroup" priority="0x0600">
  <Parent guid="VSMainMenu" id="Edit"/>
</Group>

Você terá acesso completo ao IntelliSense para os posicionamentos, facilitando encontrar o local adequado.

IntelliSense pai do VSCT.

<Button> também precisa ser atualizado. Você dará a ele um novo ícone atualizando o id<Icon> atributo do elemento para PasteAppend. Atualize o <ButtonText> texto com um nome bom e descritivo, e atualize o <LocCanonicalName> com o nome técnico do seu comando - este é o nome mostrado aos usuários quando eles atribuem atalhos de teclado personalizados ao seu comando na caixa de diálogo Ferramentas > Opções > Ambiente > Teclado.

<Button guid="InsertGuid" id="MyCommand" priority="0x0100" type="Button">
  <Parent guid="InsertGuid" id="MyMenuGroup" />
  <Icon guid="ImageCatalogGuid" id="PasteAppend" />
  <CommandFlag>IconIsMoniker</CommandFlag>
  <Strings>
    <ButtonText>Insert GUID</ButtonText>
    <LocCanonicalName>.Edit.InsertGuid</LocCanonicalName>
  </Strings>
</Button>

Observação

Inicie sempre o <LocCanonicalName> com um caractere de ponto. Ele garante que nenhum outro texto seja automaticamente acrescentado e o ponto não seja mostrado.

Você pode usar os milhares de ícones disponíveis na biblioteca de imagens do Visual Studio e até mesmo obter uma visualização mostrada no IntelliSense:

Ícone do VSCT IntelliSense.

Agora, você atualizou o nome, ícone e localização do nosso comando e é hora de escrever algum código para inserir o guid no editor de texto.

Abra o arquivo /Commands/MyCommand.cs e modifique-o para inserir um novo guid quando executado:

using System;
using Community.VisualStudio.Toolkit;
using EnvDTE;
using Microsoft.VisualStudio.Shell;
using Task = System.Threading.Tasks.Task;

namespace InsertGuid
{
    [Command(PackageIds.MyCommand)]
    internal sealed class MyCommand : BaseCommand<MyCommand>
    {
        protected override async Task ExecuteAsync(OleMenuCmdEventArgs e)
        {
            await Package.JoinableTaskFactory.SwitchToMainThreadAsync();
            DocumentView docView = await VS.Documents.GetActiveDocumentViewAsync();
            if (docView?.TextView == null) return;
            SnapshotPoint position = docView.TextView.Caret.Position.BufferPosition;
            docView.TextBuffer?.Insert(position, Guid.NewGuid().ToString()); 
        }
    }
}

Você está usando o VS objeto para obter a visualização de texto do editor ativo e, em seguida, insira o guid na posição do cursor do buffer de texto. VS é um objeto estático que fornece acesso aos elementos da interface do usuário IDE do Visual Studio; veja sua definição em VS.cs no repositório GitHub do VSIX Community Toolkit.

Observação

Você verá await JoinableTaskFactory.SwitchToMainThreadAsync() e ThreadHelper.ThrowIfNotOnUIThread() em muitos lugares neste kit de ferramentas da comunidade. Eles lidam com as melhores práticas de comutação de threads e você não precisa saber quando e como usá-los neste momento - avisos do compilador com correções de código (lâmpadas) torna isso super fácil.

O primeiro rascunho da nossa extensão está agora completo e é tempo de testá-lo.

Execução e depuração

Executar sua extensão é tão fácil quanto executar qualquer outro projeto .NET. Basta pressionar F5 para executar com o depurador anexado ou Ctrl+F5 para executar sem.

Isso iniciará a instância experimental do Visual Studio com sua extensão instalada. A instância experimental é sua versão regular do Visual Studio, mas com configurações e extensões separadas instaladas. Ajuda a manter as coisas separadas.

Quando a instância experimental for iniciada, você verá o comando Inserir GUID no menu principal Editar .

Insira o comando GUID localizado no menu principal Editar.

Abra qualquer arquivo baseado em texto e execute o comando para inserir um novo guid. É isso!

Resumo

Agora você criou sua primeira extensão que adiciona um botão de comando ao menu principal e interage com o editor de texto quando executado.

Parabéns;!!

Você pode encontrar o código para essa extensão no repositório de exemplos.