同时使用 VisualStudio.Extensibility SDK 和 VSSDK
虽然 VisualStudio.Extensibility 模型主要是为了在 devenv.exe 进程之外托管扩展,但可以在 Visual Studio 进程中运行的扩展中使用 VisualStudio.Extensibility SDK API,并利用 Microsoft.VisualStudio.Sdk 包提供的传统扩展性 API。
支持进程内使用的目的是让早期采用者能够使用新的 VisualStudio.Extensibility API,同时依靠 Microsoft.VisualStudio.Sdk 来弥补任何功能差距。
本文档是有关使用 VisualStudio.Extensibility SDK in-proc 的不同选项的快速演练。
如果要开发新扩展,我们建议的方法是按照 本教程创建一个在进程内托管的 VisualStudio.Extension。 使用此方法,除了能够注入 VSSDK 和 MEF 服务外,还可以使用 VisualStudio.Extensibility SDK 的完整功能。
如果有现有的 VSSDK 扩展,可以按照这些提示 在扩展中使用新的 VisualStudioExtensibility 实例。
如果要使用 VisualStudio.Extensibility SDK 将命令、调试可视化器、工具窗口添加到现有的 VSSDK 扩展中,可以参考 这些提示,在同一 VS 扩展项目中托管 VSSDK 扩展和 VisualStudio.Extensibility 扩展。
创建第一个与 VSSDK 兼容的 VisualStudio.Extensibility 扩展扩展
虽然 VisualStudio.Extensibility 模型主要是为了在 devenv.exe 进程之外托管扩展,但从 Visual Studio 2022 17.4 预览版 1 开始,可以生成一个托管在 devenv.exe 中的 VisualStudio.Extensibility 扩展性扩展插件,并且可以使用 Microsoft.VisualStudio.Sdk 包提供的传统扩展性 API。
先决条件
- Visual Studio 2022 版本 17.9 预览版 1 或更高版本,带有
Visual Studio extension development
工作负载。 - 如果要从早期版本更新,请确保卸载 VisualStudio.Extensibility Project System 以避免潜在的冲突。
创建扩展项目
- 使用 VisualStudio.Extensibility Extension with VSSDK Compatibility 模板创建新的解决方案。
调试扩展
按
F5
开始调试,这会生成扩展并将其部署到正在使用的 Visual Studio 版本的实验实例。 调试程序应该会在扩展加载后自动附加。可以在
Extensions
菜单中找到命令,如下图所示:
从 VisualStudio.Extensibility 扩展使用 Visual Studio SDK 服务
与 VS-SDK 兼容的扩展项目引用 Microsoft.VisualStudio.Sdk 包,该包允许访问所有 Visual Studio SDK 的服务。
传统上,此类服务通过 MEF 或 AsyncServiceProvider使用。 建议改用 VisualStudio.Extensibility 扩展程序来进行 .NET 依赖关系注入。
MefInjection<TService>
和 AsyncServiceProviderInjection<TService, TInterface>
类(两者都来自 Microsoft.VisualStudio.Extensibility.VSSdkCompatibility
命名空间),通过将它们添加到通过依赖项注入实例化的类的构造函数(如命令、工具窗口或扩展部件)来使用 Visual Studio SDK 的服务。
以下示例演示如何将 DTE2
和 IBufferTagAggregatorFactoryService
服务添加到命令。
[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),
};
VSSDK 兼容的 VisualStudio.Extensibility 扩展的剖析
虽然将 VisualStudio.Extensibility Extension with VSSDK Compatibility 模板用于设置整个项目,但了解与 VS-SDK 兼容的 VisualStudio.Extensibility 扩展插件的基本组件以及它与 “创建第一个扩展”指南中所述的常见变体有何不同,这非常有用。
TargetFramework 和 VssdkCompatibleExtension
扩展项目必须面向目标 Visual Studio 版本使用的 .NET 版本。 对于 Visual Studio 2022,扩展项目必须以 .NET Framework 4.7.2 为目标。
扩展项目还必须包含VssdkCompatibleExtension
属性,且该属性设为 true
。
<PropertyGroup>
<VssdkCompatibleExtension>true</VssdkCompatibleExtension>
</PropertyGroup>
RequiresInProcessHosting 属性
Extension
类必须使用 RequiresInProcessHosting = true
属性进行配置,该属性将扩展标识为进程内的 。
[VisualStudioContribution]
internal class MyExtension : Extension
{
public override ExtensionConfiguration? ExtensionConfiguration => new()
{
RequiresInProcessHosting = true,
};
...
程序包清单
扩展项目必须包含名为 source.extension.vsixmanifest
的程序包清单。 Installation
标记必须将 ExtensionType
设置为 VSSDK+VisualStudio.Extensibility
。
<?xml version="1.0" encoding="utf-8"?>
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
<Metadata>
<Identity Id="MyExtensionId.f14b8c45-154f-4584-abd7-9ec22af003e2" Version="1.0" Language="en-US" Publisher="Microsoft" />
<DisplayName>My extension</DisplayName>
<Description xml:space="preserve">My extension's description.</Description>
</Metadata>
<Installation ExtensionType="VSSDK+VisualStudio.Extensibility">
<InstallationTarget Id="Microsoft.VisualStudio.Community" Version="[17.9,18.0)">
<ProductArchitecture>amd64</ProductArchitecture>
</InstallationTarget>
<InstallationTarget Id="Microsoft.VisualStudio.Community" Version="[17.9,18.0)">
<ProductArchitecture>arm64</ProductArchitecture>
</InstallationTarget>
</Installation>
<Prerequisites>
<Prerequisite Id="Microsoft.VisualStudio.Component.CoreEditor" Version="[17.0,)" DisplayName="Visual Studio core editor" />
</Prerequisites>
<Assets>
<Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%;PkgdefProjectOutputGroup|" />
</Assets>
</PackageManifest>
从现有 VSSDK 扩展使用 VisualStudio.Extensibility
对于现有的 VSSDK 扩展,另一个选项是通过服务提供商查询 VisualStudioExtensibility 实例并利用其方法。 此方法允许您在现有组件中使用 VisualStudio.Extensibility SDK 的新 API 表面区域。 在想要使用新 API 查询项目信息、文档管理而不创建新的基于 VisualStudio.Extensibility 的扩展的情况下,此选项非常有用。
下面是一个示例代码片段,演示如何在 VSSDK 包中使用 VisualStudioExtensibility
:
- 在
.csproj
文件中,包括对 VisualStudio.Extensibility API 的包引用:
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Extensibility" Version="17.9.2092" />
</ItemGroup>
- 现在可以通过包或其他组件中的
GetServiceAsync
方法查询 VisualStudioExtensibility 实例:
...
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);
...
}
}
向现有 VSSDK 扩展项目添加 VisualStudio.Extensibility 扩展
如果您希望在现有的 VSSDK 扩展中使用 VisualStudio.Extensibility SDK 贡献组件(例如工具窗口、编辑器侦听器),则必须按照附加步骤在项目中创建一个 VisualStudio.Extensibility Extension 实例。
需要使用 SDK 样式
.csproj
才能使用 VisualStudio.Extensibility SDK 包。 对于现有项目,您可能需要将.csproj
更新为 SDK 样式的版本。删除
Microsoft.VSSDK.BuildTools
的包引用,而是添加 VisualStudio.Extensibility 的包引用。
<PackageReference Include="Microsoft.VisualStudio.Extensibility.Sdk" Version="17.9.2092" />
<PackageReference Include="Microsoft.VisualStudio.Extensibility.Build" Version="17.9.2092" />
- 将
VssdkCompatibleExtension
属性添加到项目文件,将其设置为true
。 此属性将启用一些 VSSDK 功能以实现兼容性。
<PropertyGroup>
<VssdkCompatibleExtension>true</VssdkCompatibleExtension>
</PropertyGroup>
- 创建继承自
Extension
基类的新扩展类,并设置 RequiresInProcessHosting 属性,如前所示。 - 修改
source.extension.vsixmanifest
文件,将ExtensionType="VSSDK+VisualStudio.Extensibility"
添加到Installation
标记。
<Installation ExtensionType="VSSDK+VisualStudio.Extensibility">
现在,可以将 VisualStudio.Extensibility 的所有功能与现有的 VSSDK 扩展一起使用。