你的第一个 Visual Studio 扩展

本文将引导你完成一些简单的步骤,以便启动并运行第一个 Visual Studio 扩展。 Visual Studio 扩展是使用 .NET Framework 和 C# 编写的。 如果你已经是 .NET 开发人员,你会发现编写扩展类似于编写大多数其他 .NET 程序和库。

今天你要编写的扩展将添加一个命令,该命令在执行时会将一个新的guid插入文本编辑器。 它非常简单、有用,并很好地介绍了扩展开发的各个方面。

如果你是视觉型学习者,请观看一个人按照教程操作的简短视频。

在开始编写第一个 Visual Studio 扩展(这很容易,我承诺!)之前,请确保你已 获得所需的工具

创建项目

有几个项目模板可供选择,因此你想要做出正确的选择。 此社区工具包中使用的模板,其名称中都有标识(社区)。

VSIX 项目 w/Command (Community) 模板附带了一个已挂钩的命令,因此可以轻松地从那里开始。 对于大多数扩展而言,这是一个很好的起点。 如果您知道需要一个工具窗口,请使用带有工具窗口(社区版)的 VSIX 项目模板。 它还具有用于打开工具窗口的命令。

空 VSIX 项目(社区)VSIX 项目(社区) 模板用于仅用于 MEF 的扩展或其他复杂场景。

这次,你将选择 VSIX 项目 w/Command (Community) 模板,如下面的屏幕截图所示。

显示 VSIX 项目模板的“新建项目”对话框。

选择项目模板后,需要为项目命名。 将其命名为 InsertGuid

配置新项目。

点击“ 创建 ”按钮后,最终应会看到如下所示的基本 VSIX 项目:

新建项目文件和文件夹。

重要文件

我们来看看最重要的文件。

InsertGuidPackage.cs 称为 Package 类。 Visual Studio 调用其 InitializeAsync(...) 方法来初始化扩展。 从此处可以添加事件侦听器并注册命令、工具窗口、设置和其他内容。

source.extension.vsixmanifest 是扩展的清单文件。 它包含元数据,如标题和说明,但也包含有关扩展包含的内容的信息。

VSCommandTable.vsct 是一个 XML 文件,其中以声明方式定义命令和键绑定,以便它们可以注册到 Visual Studio。

Commands/MyCommand.csVSCommandTable.vsct 文件中定义的命令的命令处理程序。 它通过单击按钮来控制命令执行时会发生什么情况。

修改命令

首先,你需要确保命令在 Visual Studio 菜单系统中具有正确的名称、图标和位置。

打开 VSCommandTable.vsct 文件,找到一个 <Group> 和一个 <Button>。 请注意该按钮如何将组指定为其父级,而该组的父级又是内置的 VSMainMenu/Tools 菜单。

对于您的扩展,您希望 “插入 GUID” 命令按钮位于 “编辑” 主菜单下,因此您将把这个组重新放置到“编辑”菜单下。 将 工具 替换为 “编辑” ,就像在以下代码片段中一样:

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

你可以获得完整的 IntelliSense 位置,以便轻松找到合适的位置。

VSCT 父级 IntelliSense。

<Button> 也需要更新。 通过将元素的属性更新为PasteAppend为其赋予新图标。 使用一个良好的描述性名称更新 <ButtonText> 文本,并使用命令的技术名称更新 <LocCanonicalName> 。这些是用户在 工具 > 选项 > 环境 > 键盘 对话框中为命令分配自定义键盘快捷键时显示的名称。

<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>

注释

始终以 <LocCanonicalName> 点字符开头。 它确保不会自动预写其他文本,并且不会显示点。

可以使用 Visual Studio 图像库中提供的数千个图标,甚至可以获取 IntelliSense 中显示的预览:

VSCT 图示 IntelliSense。

现在,你已更新命令的名称、图标和位置,现在可以编写一些代码以将 guid 插入文本编辑器中。

打开 /Commands/MyCommand.cs 文件,并在执行时修改其内容以插入一个新的 guid。

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()); 
        }
    }
}

你正在使用 VS 对象获取活动编辑器的文本视图,然后将 GUID 插入到其文本缓冲区的插入点位置。 VS是一个静态对象,它提供对 Visual Studio IDE UI 元素的访问权限;在 VSIX 社区工具包 GitHub 存储库中的VS.cs中查看其定义。

注释

你会在此社区工具包的许多地方看到await JoinableTaskFactory.SwitchToMainThreadAsync()ThreadHelper.ThrowIfNotOnUIThread()。 它们处理线程切换的最佳实践,目前您无需知道何时以及如何使用它们,编译器通过代码修复提示(灯泡提示)发出的警告,使这一点变得非常简单。

扩展的第一个草稿现已完成,是时候测试它了。

运行和调试

运行扩展与运行任何其他 .NET 项目一样简单。 只需按 F5 以附加调试器方式运行,或者按 Ctrl+F5 运行而不附加调试器。

这样做将启动已安装扩展的 Visual Studio 实验实例。 实验实例是 Visual Studio 的常规版本,但安装了单独的设置和扩展。 它有助于保持事物的分离。

实验实例启动时,应在“编辑”主菜单中看到“插入 GUID”命令。

在“编辑主”菜单中插入 GUID 命令。

打开任何基于文本的文件并执行命令以插入新的 guid。 就是这样!

概要

现已创建第一个扩展,该扩展将命令按钮添加到主菜单,并在执行时与文本编辑器交互。

祝贺!!

可以在 示例存储库中找到此扩展的代码。