将 VSIX 功能添加到 C# Class 库
Add VSIX features to C# Class Library
我有一个现有的单文件生成器(位于 C# Class 库中)。如何将 VSIX 项目级功能添加到此项目?最终目标是编译我的 class 库项目并获得 VSIX。
(我实际上是在回答我自己的问题。这与 SIngle-file generator changes in Visual Studio 2017 有关 - 但那个问题并不是问我在这里回答的问题。)
首先,
您的单文件生成器 class 需要具有适当的 class 级属性:
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.Shell;
using VSLangProj80;
[ComVisible(true)]
[Guid("your-unique-identifier")]
[CodeGeneratorRegistration(
typeof(MyCustomTool),
"MyCustomTool",
vsContextGuids.vsContextGuidVCSProject,
GeneratesDesignTimeSource = true,
GeneratorRegKeyName = "MyCustomTool"
)]
[ProvideObject(
typeof(MyCustomTool),
RegisterUsing = RegistrationMethod.CodeBase
)]
public sealed class MyCustomTool : IVsSingleFileGenerator {
所有这些属性将确保在 VSIX 中正确生成 .pkgdef 文件。 .pkgdef 文件包含用于向 Visual Studio.
注册单文件生成器的注册表项
第二,
向您的项目添加一个文本文件 "source.extension.vsixmanifest"。它的 "Build Action" 应该是 "None." 给它一些默认文本:
<?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="MyCustomTool.MyCompany.another-random-guid" Version="1.0" Language="en-US" Publisher="MyCompany" />
<DisplayName>MyCustomTool</DisplayName>
<Description>Helpful information</Description>
</Metadata>
<Installation>
<InstallationTarget Id="Microsoft.VisualStudio.Community" Version="[15.0]" />
</Installation>
<Dependencies>
<Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework" d:Source="Manual" Version="[4.5,)" />
</Dependencies>
<Prerequisites>
<Prerequisite Id="Microsoft.VisualStudio.Component.CoreEditor" Version="[15.0,16.0)" DisplayName="Visual Studio core editor" />
</Prerequisites>
</PackageManifest>
其中大部分内容都非常深奥。在下一步中,我们将制作它以便您可以使用设计器编辑此文件。
第三
(并回答原始问题),您需要手动处理 .csproj 文件(您的 C# Class 库文件)。具体需要添加以下内容:
<PropertyGroup>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<ProjectTypeGuids>{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
</PropertyGroup>
<ItemGroup>
<None Include="source.extension.vsixmanifest">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<PropertyGroup>
<UseCodebase>true</UseCodebase>
</PropertyGroup>
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
那么,我们在这里做了什么?让我们分解一下。
首先,我们设置了 Visual Studio 工具集所在位置的路径。毕竟,现在这是一个 "extensions project." 所以,它需要知道 VS-SDK 的位置。
然后,我们更改了 "ProjectTypeGuids"(这可能不在您的项目文件中)。最初,它只包含 C# 的 guid(即 "FAE04EC0-..." guid)。现在,它还包含 VSIX 的 guid(即“82b43b9b-...”guid)。
我们还确保 "source.extension.vsixmanifest" 文件使用其新颖的设计器(而不是手动编辑文件)。
"UseCodeBase" 元素很重要。此元素可防止您被迫向系统的 COM 注册表注册您的生成器。相反,Visual Studio 只会从安装位置加载您的生成器。
在底部,我们为 VS-SDK 导入 MsBuild 内容。
第四,
重新加载您的项目。转到“项目属性”屏幕,您会在底部看到一个新的 "VSIX" 部分。打开该部分并选中 "Create VSIX Container during build" 复选框。
此时,您还可以仔细检查"source.extension.vsixmanifest"文件。根据您的发电机的花哨程度,您可以根据需要进行更改。 (我在上面粘贴的文件内容与我在项目中使用的内容几乎完全相同。)
最后,
你可以编译你的项目了。在 bin 文件夹中,您会找到 MyCustomTool.dll 和 MyCustomTool.vsix。 .vsix 文件只是一个 zip 文件。在 .vsix 中,您会发现 MyCustomTool.pkgdef.
如果我们一切都正确,.pkgdef 文件应该如下所示:
[$RootKey$\Generators\{FAE04EC1-301F-11D3-BF4B-00C04F79EFBC}\MyCustomTool]
@="MyCustomTool"
"CLSID"="{your-unique-identifier}"
"GeneratesDesignTimeSource"=dword:00000001
[$RootKey$\CLSID\{your-unique-identifier}]
@="MyCustomTool"
"InprocServer32"="$WinDir$\SYSTEM32\MSCOREE.DLL"
"Class"="MyCustomTool"
"CodeBase"="$PackageFolder$\MyCustomTool.dll"
"ThreadingModel"="Both"
而且,我认为这是我写过的最长的 SO 答案。可能只有 5 个人会读到这篇文章:)
如果不是在您的 class 上实现 IVsSingleFileGenerator
,您的 class 继承自抽象 class BaseCodeGeneratorWithSite
继承自抽象 class BaseCodeGenerator
实现 IVsSingleFileGenerator
您需要将以下属性添加到您的 class,以避免错误消息 "Cannot find custom tool '...' on this system":
[ClassInterface(ClassInterfaceType.None)]
原因是抽象 class BaseCodeGeneratorWithSite
不是 COM 可见的。
我有一个现有的单文件生成器(位于 C# Class 库中)。如何将 VSIX 项目级功能添加到此项目?最终目标是编译我的 class 库项目并获得 VSIX。
(我实际上是在回答我自己的问题。这与 SIngle-file generator changes in Visual Studio 2017 有关 - 但那个问题并不是问我在这里回答的问题。)
首先,
您的单文件生成器 class 需要具有适当的 class 级属性:
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.Shell;
using VSLangProj80;
[ComVisible(true)]
[Guid("your-unique-identifier")]
[CodeGeneratorRegistration(
typeof(MyCustomTool),
"MyCustomTool",
vsContextGuids.vsContextGuidVCSProject,
GeneratesDesignTimeSource = true,
GeneratorRegKeyName = "MyCustomTool"
)]
[ProvideObject(
typeof(MyCustomTool),
RegisterUsing = RegistrationMethod.CodeBase
)]
public sealed class MyCustomTool : IVsSingleFileGenerator {
所有这些属性将确保在 VSIX 中正确生成 .pkgdef 文件。 .pkgdef 文件包含用于向 Visual Studio.
注册单文件生成器的注册表项第二,
向您的项目添加一个文本文件 "source.extension.vsixmanifest"。它的 "Build Action" 应该是 "None." 给它一些默认文本:
<?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="MyCustomTool.MyCompany.another-random-guid" Version="1.0" Language="en-US" Publisher="MyCompany" />
<DisplayName>MyCustomTool</DisplayName>
<Description>Helpful information</Description>
</Metadata>
<Installation>
<InstallationTarget Id="Microsoft.VisualStudio.Community" Version="[15.0]" />
</Installation>
<Dependencies>
<Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework" d:Source="Manual" Version="[4.5,)" />
</Dependencies>
<Prerequisites>
<Prerequisite Id="Microsoft.VisualStudio.Component.CoreEditor" Version="[15.0,16.0)" DisplayName="Visual Studio core editor" />
</Prerequisites>
</PackageManifest>
其中大部分内容都非常深奥。在下一步中,我们将制作它以便您可以使用设计器编辑此文件。
第三
(并回答原始问题),您需要手动处理 .csproj 文件(您的 C# Class 库文件)。具体需要添加以下内容:
<PropertyGroup>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<ProjectTypeGuids>{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
</PropertyGroup>
<ItemGroup>
<None Include="source.extension.vsixmanifest">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<PropertyGroup>
<UseCodebase>true</UseCodebase>
</PropertyGroup>
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
那么,我们在这里做了什么?让我们分解一下。
首先,我们设置了 Visual Studio 工具集所在位置的路径。毕竟,现在这是一个 "extensions project." 所以,它需要知道 VS-SDK 的位置。
然后,我们更改了 "ProjectTypeGuids"(这可能不在您的项目文件中)。最初,它只包含 C# 的 guid(即 "FAE04EC0-..." guid)。现在,它还包含 VSIX 的 guid(即“82b43b9b-...”guid)。
我们还确保 "source.extension.vsixmanifest" 文件使用其新颖的设计器(而不是手动编辑文件)。
"UseCodeBase" 元素很重要。此元素可防止您被迫向系统的 COM 注册表注册您的生成器。相反,Visual Studio 只会从安装位置加载您的生成器。
在底部,我们为 VS-SDK 导入 MsBuild 内容。
第四,
重新加载您的项目。转到“项目属性”屏幕,您会在底部看到一个新的 "VSIX" 部分。打开该部分并选中 "Create VSIX Container during build" 复选框。
此时,您还可以仔细检查"source.extension.vsixmanifest"文件。根据您的发电机的花哨程度,您可以根据需要进行更改。 (我在上面粘贴的文件内容与我在项目中使用的内容几乎完全相同。)
最后,
你可以编译你的项目了。在 bin 文件夹中,您会找到 MyCustomTool.dll 和 MyCustomTool.vsix。 .vsix 文件只是一个 zip 文件。在 .vsix 中,您会发现 MyCustomTool.pkgdef.
如果我们一切都正确,.pkgdef 文件应该如下所示:
[$RootKey$\Generators\{FAE04EC1-301F-11D3-BF4B-00C04F79EFBC}\MyCustomTool]
@="MyCustomTool"
"CLSID"="{your-unique-identifier}"
"GeneratesDesignTimeSource"=dword:00000001
[$RootKey$\CLSID\{your-unique-identifier}]
@="MyCustomTool"
"InprocServer32"="$WinDir$\SYSTEM32\MSCOREE.DLL"
"Class"="MyCustomTool"
"CodeBase"="$PackageFolder$\MyCustomTool.dll"
"ThreadingModel"="Both"
而且,我认为这是我写过的最长的 SO 答案。可能只有 5 个人会读到这篇文章:)
如果不是在您的 class 上实现 IVsSingleFileGenerator
,您的 class 继承自抽象 class BaseCodeGeneratorWithSite
继承自抽象 class BaseCodeGenerator
实现 IVsSingleFileGenerator
您需要将以下属性添加到您的 class,以避免错误消息 "Cannot find custom tool '...' on this system":
[ClassInterface(ClassInterfaceType.None)]
原因是抽象 class BaseCodeGeneratorWithSite
不是 COM 可见的。