Добавить функции 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.

Другие вопросы по тегам