Введение в расширения Visual Studio
Visual Studio, гигант среди интегрированных сред разработки (IDE), является мощным инструментом, который можно настроить под ваши потребности с помощью расширений. Эти дополнения могут преобразить ваш опыт программирования, сделав его более эффективным, приятным и персонализированным. В этой статье мы углубимся в мир разработки расширений Visual Studio с помощью C#, руководя вас через процесс с помощью практических примеров, пошаговых инструкций и немного юмора, чтобы сделать все интереснее.
Что вам нужно для начала
Прежде чем приступить к подробностям, убедитесь, что у вас есть необходимые инструменты:
- Visual Studio: Вам нужна полная версия Visual Studio, а не только Community Edition, для разработки расширений.
- Visual Studio SDK: Это крайне важно для разработки расширений. Вы можете установить его во время установки Visual Studio или позже.
Типы расширений
Расширения Visual Studio бывают двух основных типов: VSPackages и MEF (Managed Extensibility Framework) расширения.
- VSPackages: Эти расширения используются для взаимодействия с командами, окнами инструментов и проектами. Они более сложны, но предлагают более глубокую интеграцию с Visual Studio.
- MEF Расширения: Эти расширения проще и в основном используются для расширения или настройки редактора Visual Studio. Они идеальны для добавления новых языковых функций или настройки процесса редактирования.
Создание вашего первого расширения
Давайте начнем с простого MEF расширения, чтобы разогреться.
Шаг 1: Настройка вашего проекта
- Откройте Visual Studio и перейдите к
Файл
>Новый
>Проект
. - Выберите “Extensibility” в разделе “Visual C#”.
- Выберите “VSIX Project” и назовите ваш проект, например, “MyFirstExtension”.
Шаг 2: Добавление пользовательской команды
Чтобы добавить пользовательскую команду, вам нужно создать класс, наследующийся от AsyncPackage
и реализующий необходимые интерфейсы.
using Microsoft.VisualStudio.Shell;
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
namespace MyFirstExtension
{
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
[InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
[Guid("Your-GUID-Here")]
[ProvideMenuResource("Menus.ctmenu", 1)]
public sealed class MyFirstExtensionPackage : AsyncPackage
{
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
await base.InitializeAsync(cancellationToken, progress);
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var commandService = this.GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
if (commandService != null)
{
var menuCommandID = new CommandID(new Guid("Your-GUID-Here"), 0x100);
var menuItem = new MenuCommand(MenuItemCallback, menuCommandID);
commandService.AddCommand(menuItem);
}
}
private void MenuItemCallback(object sender, EventArgs e)
{
// Ваша логика пользовательской команды здесь
System.Windows.MessageBox.Show("Привет из MyFirstExtension!");
}
}
}
Шаг 3: Определение меню
Добавьте файл .vsct
для определения пункта меню.
<CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<Commands>
<Menu guid="guidMyFirstExtensionCmdSet" id="MyMenuGroup" priority="0x0600" type="Menu">
<Parent guid="guidSHLMainMenu" id="IDG_VS_MM_TOOLSADDINS1"/>
<Strings>
<ButtonText>Мое первое расширение</ButtonText>
<CommandName>MyFirstExtension</CommandName>
</Strings>
</Menu>
</Commands>
<Buttons>
<Button guid="guidMyFirstExtensionCmdSet" id="MyCommand" priority="0x0100" type="Button">
<Parent guid="guidMyFirstExtensionCmdSet" id="MyMenuGroup" />
<Icon guid="guidImages" id="bmpPic1" />
<Strings>
<ButtonText>Моя команда</ButtonText>
</Strings>
</Button>
</Buttons>
<Bitmaps>
<Bitmap guid="guidImages" href="Resources\MyIcon.png" usedList="bmpPic1, bmpPic2, bmpPicSearch, bmpPicX, bmpPicArrows, bmpPicStrikethrough"/>
</Bitmaps>
</CommandTable>
Расширение меню и команд
Одним из самых распространенных расширений является добавление пользовательских пунктов меню и команд. Вот краткий обзор того, как вы можете расширить меню и команды:
Расширение окон инструментов
Окна инструментов — еще одна область, где вы можете добавить значительную ценность. Вот как вы можете создать пользовательское окно инструментов:
- Создать класс окна инструментов: Наследуйте от
ToolWindowPane
. - Зарегистрировать окно инструментов: Используйте атрибут
ProvideToolWindow
. - Инициализировать окно инструментов: Переопределите метод
CreateToolWindowPane
в вашем классе пакета.
[ProvideToolWindow(typeof(MyToolWindow), Style = VsDockStyle.Tabbed, Orientation = ToolWindowOrientation.Right)]
public sealed class MyFirstExtensionPackage : AsyncPackage
{
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
await base.InitializeAsync(cancellationToken, progress);
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var toolWindow = this.FindToolWindow(typeof(MyToolWindow), 0, true);
if (toolWindow != null)
{
var window = (MyToolWindow)toolWindow;
window.Frame.Caption = "Мое пользовательское окно инструментов";
window.Visible = true;
}
}
}
public class MyToolWindow : ToolWindowPane
{
public MyToolWindow() : base(null)
{
this.Caption = "Мое пользовательское окно инструментов";
this.Content = new MyToolWindowControl();
}
}
public class MyToolWindowControl : UserControl
{
public MyToolWindowControl()
{
this.Content = new TextBlock { Text = "Привет из моего пользовательского окна инструментов!" };
}
}
Расширения редактора и языковых служб
Если вы хотите расширить редактор или добавить поддержку новых языков, вам придется углубиться в мир языковых служб.
- Создать языковую службу: Реализуйте интерфейс
ILanguageService
. - Зарегистрировать языковую службу: Используйте атрибут
ProvideLanguageService
.
[ProvideLanguageService(typeof(MyLanguageService), "MyLanguage", 100)]
public sealed class MyFirstExtensionPackage : AsyncPackage
{
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
await base.InitializeAsync(cancellationToken, progress);
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
// Инициализируйте вашу языковую службу здесь
}
}
public class MyLanguageService : ILanguageService
{
public void InitializeService(IServiceProvider serviceProvider, ITextBuffer textBuffer)
{
// Инициализируйте вашу языковую службу здесь
}
public void ShutdownService(IServiceProvider serviceProvider, ITextBuffer textBuffer)
{
// Завершите вашу языковую службу здесь
}
}
Публикация вашего расширения
После того, как вы разработали и протестировали ваше расширение, пришло время поделиться им с миром. Вот как вы можете опубликовать его в магазине Visual Studio:
- Упакуйте ваше расширение: Используйте шаблон проекта
VSIX
для создания файла.vsix
. - Отправьте в магазин: Перейдите в магазин Visual Studio, создайте учетную запись, если у вас ее нет, и отправьте ваш файл
.vsix
на проверку.
Лучшие расширения для вдохновения
Прежде чем начать строить, всегда полезно посмотреть, что сделали другие. Вот некоторые лучшие расширения, которые могут вдохновить вас:
- IntelliCode: Использует ИИ для улучшения опыта программирования с помощью умных предложений и автодополнения кода.
- Roslynator: Предоставляет анализ кода и исправления для написания более чистого кода.
- Live Share: Включает реальное сотрудничество над кодом.
- CodeMaid: Упрощает поддержку кода, организуя и очищая код.
Заключение
Разработка расширений Visual Studio — это полезное путешествие, которое может значительно улучшить ваш опыт программирования и повысить производительность. От простых пунктов меню до сложных языковых служб возможности безграничны. Помните, ключ к освоению разработки расширений — практика и желание учиться. Итак, вперед, будьте креативны и создайте что-то удивительное!