Добавить функции VSIX в библиотеку классов C#
У меня есть генератор одного файла (размещенный в библиотеке классов C#). Как добавить функции уровня проекта VSIX в этот проект? Конечная цель - скомпилировать мой проект библиотеки классов и получить VSIX.
(На самом деле я отвечаю на свой вопрос. Это связано с изменениями генератора файлов SIngle в Visual Studio 2017 - но этот вопрос не спрашивал, что я отвечаю здесь.)
2 ответа
Прежде всего,
ваш класс Генератора одного файла должен иметь соответствующие атрибуты уровня класса:
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 {
Все эти атрибуты обеспечат правильное создание файла.pkgdef в вашей VSIX. Файл.pkgdef содержит записи реестра, которые используются для регистрации генератора одного файла в Visual Studio.
Во-вторых,
Добавьте текстовый файл "source.extension.vsixmanifest" в ваш проект. Его "Build Action" должно быть "Нет". Дайте ему некоторый текст по умолчанию:
<?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#). В частности, вам нужно добавить следующее:
<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. В конце концов, теперь это "проект расширений". Таким образом, он должен знать, где находится VS-SDK.
Затем мы изменили "ProjectTypeGuids" (которого, вероятно, не было в вашем файле проекта для начала). Первоначально он просто включал в себя руководство для C# (это руководство "FAE04EC0-..."). Теперь он также включает в себя руководство для VSIX (это руководство "82b43b9b-...").
Мы также позаботились о том, чтобы файл "source.extension.vsixmanifest" использовал новый, необычный дизайнер (вместо редактирования файла вручную).
Элемент "UseCodeBase" важен. Этот элемент предотвращает принудительную регистрацию вашего генератора в системном реестре COM. Вместо этого Visual Studio просто загрузит ваш генератор с места установки.
Внизу мы импортируем материал MsBuild для VS-SDK.
В-четвертых,
Загрузите ваш проект обратно. Перейдите на экран "Свойства проекта", и вы увидите новый раздел "VSIX" внизу. Откройте этот раздел и установите флажок "Создать контейнер VSIX во время сборки".
На этом этапе вы также можете дважды проверить файл "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"
И я думаю, что это самый длинный ответ, который я написал. И, вероятно, только 5 человек когда-либо будут читать это:)
Если вместо реализации IVsSingleFileGenerator
в вашем классе ваш класс наследуется от абстрактного класса BaseCodeGeneratorWithSite
что наследует от абстрактного класса BaseCodeGenerator
который реализует IVsSingleFileGenerator
вам нужно добавить следующий атрибут в ваш класс, чтобы избежать сообщения об ошибке "Не удается найти пользовательский инструмент"... в этой системе:
[ClassInterface(ClassInterfaceType.None)]
Причина в том, что абстрактный класс BaseCodeGeneratorWithSite
не виден COM.