Вступление
Для разработчиков расширений для Visual Studio (VSX - Visual Studio Extensibility) часто бывает важно выпустить расширение не только для последней версии среды разработки (в настоящее время – это Visual Studio 2010), но и обеспечить совместимость с предыдущими версиями для тех пользователей, которые еще не перешли на последнюю версию Visual Studio.
В данной статье рассматривается вопрос, связанный с разработкой расширений для Visual Studio 2005, а именно, рассматривается как можно добавить поддержку VSCT (Visual Studio Command Table) для проектов расширения возможностей Visual Studio 2005 (Whidbey). По умолчанию проекты расширения Visual Studio 2005 используют С++ подобный формат описания команд среды разработки – CTC (Command Table Configuration). Начиная с версии Visual Studio 2008, вместо это устаревшего формата в VSSDK используется XML-формат VSCT (Visual Studio Command Table).
VSX проект – это обычно некий пакет (Package) для Visual Studio, который добавляет какую-либо дополнительную фукнциональность. Это может быть как добавление нескольких полезных комманд в стандартные меню, так и вплоть до интеграции нового языка программирования. Так или иначе подобные проекты обычно привносят новые элементы пользовательского интерфейса Visual Studio – команды, меню и тулбары.
Архитектура Visual Studio позволяет указать в какие группы (свои или стандартные) поместить разработанные нами команды. Это очень удобно, поскольку для помещения своих команд в среду разработки необходимо всего лишь правильно их зарегистрировать (описать).
Описание происходит в терминах групп команд, их идентификаторов GUID и ID, приоритетов и прочих свойств команд. Именно для этого существуют форматы CTC и VSCT.
ПРИМЕЧАНИЕ: команда VSX (Visual Studio Extensibility – VSX Team) выпустила VSCT PowerToy. Это штука позволяет VSX разработчикам просматривать идентификаторы GUID и ID для интересующих их команд, меню и кнопок панелей инструментов. Это сильно экономит время, когда необходимо найти ижентификаторы интересующей вас группы меню, куда вы хотите добавить свои команды. Подробнее о VSCT PowerToy можно узнать в блоге - VSX Team Blog здесь.
Форматы CTC и VSCT
Формат CTC (Command Table Configuration) – представляет собой описание команд с помощью С++ подобного синтаксиса. Пример, взятый из поста Аарона Мартина, для добавления двух элементов меню:
BUTTONS_BEGIN
// Here there is the definition of the commands placed inside the toolbars. Notice that there is
// no difference between these toolbar button definitions and the menu item definition above.
guidMenuAndCommandsCmdSet:cmdidMyGraph, guidMenuAndCommandsCmdSet:MyMainToolbarGroup, 0x100, guidOfficeIcon:msotcidGraph, BUTTON, , "C# Sample Graph Command";
guidMenuAndCommandsCmdSet:cmdidMyZoom, guidMenuAndCommandsCmdSet:MyToolbarGroup, 0x100, guidOfficeIcon:msotcidZoom, BUTTON, , "C# Sample Zoom Command";
BUTTONS_END
Формат VSCT (Visual Studio Command Table) по сути представляет собой XML представление команд и работать с ним намного удобнее (и безопаснее в плане внесения ошибок). Вот пример добавления тех же элементов меню с помощью VSCT:
<Buttons>
<!-- Here there is the definition of the commands placed inside the toolbars. Notice that there is no difference between these toolbar button definitions and the menu item definition above. -->
<Button guid="guidMenuAndCommandsCmdSet" id="cmdidMyGraph" priority="0x100" type="Button">
<Parent guid="guidMenuAndCommandsCmdSet" id="MyMainToolbarGroup"/>
<Icon guid="guidOfficeIcon" id="msotcidGraph"/>
<Strings>
<ButtonText>C# Sample Graph Command</ButtonText>
</Strings>
</Button>
<Button guid="guidMenuAndCommandsCmdSet" id="cmdidMyZoom" priority="0x100" type="Button">
<Parent guid="guidMenuAndCommandsCmdSet" id="MyToolbarGroup"/>
<Icon guid="guidOfficeIcon" id="msotcidZoom"/>
<Strings>
<ButtonText>C# Sample Zoom Command</ButtonText>
</Strings>
</Button>
</Buttons>
Итак
В апреле 2007 Аарон Мартин написал пост CTC is dead...Long Live VSCT! (Part 1), где он объявил о появлении нового XML-формата для описания команд Visual Studio, который называется VSCT. Он написал, что благодаря XML и возможностям Visual Studio для работы с ним - с этим новым форматом гораздо легче работать, чем с CTC.
Через две недели назад Джеймс Лау объявил о выходе апрельского CTP для Visual Studio 2008 SDK, который помимо прочего включал поддержку VSCT формата, и все примеры использовали уже новый формат описания команд среды разработки.
Это была отличная новость, но, к сожалению, подержка VSCT была реализована только для VS2008. Последняя версия VS SDK 4.0 RTM для Visual Studio 2005, анонсированная чуть раньше, по прежнему использовала только CTC формат. Однако в поставку VS SDK 4.0 RTM для Visual Studio 2005 вошел компилятор VSCT в предрелизном состоянии.
После установки VSSDK, этот компилятор находится здесь:
C:\Program Files\Visual Studio 2005 SDK\2007.02\Prerelease\
Было решено самостоятельно интегрировать новый компилятор в среду разработки VS2005, чтобы не поддерживать различные форматы описания команд для версий проектов расширения под VS2005 и VS2008 (а в последствии также и VS2010).
Опытом такой интеграции я решил поделиться с вами в этой статье. Ниже приведены шаги, необходимые для добавления поддержки VSCT формата в ваших VSX проектах для Visual Studio 2005. В качестве примера был взят проект C# Reference.MenuAndCommands, который входит в поставку Visual Studio SDK Version 4.0, и который изначально использует формат CTC. Этот проект можно найти здесь:
C:\Program Files\Visual Studio 2005 SDK\2007.02\VisualStudioIntegration\Samples\IDE\CSharp\Reference.MenuAndCommands\
По окончанию данной стать, после выполнения действий, указанных ниже, вы получите проект C# Reference.MenuAndCommands, использующий формат VSCT.
Последовательность действий
1. Прежде, чем мы заменим CTC на VSCT давайте убедимся, что исходный проект компилируется. Кроме того - посмотрим, как эти команды выглядят сейчас – до изменений. Нажмите клавишу F5 для запуска проекта MenuAndCommands в экспериментальной ветке реестра VSX (так называемый Experimental Hive) и убедитесь, что в меню Tools добавилось несколько новых пунктов меню. Мы будем использовать в качестве индикатора нашей работы пункт меню «C# Command Sample».

2. Первое, о чем нам необходимо позаботиться – это создание VSCT аналога для нашего файла CTC. Самый простой способ создать такой файл – это скомпилировать из имеющегося CTC файла – файл CTO. А затем на основе файла CTO восстановить файл VSCT, как указано в этой статье - How to: Create a .Vsct File from an Existing .Cto File. То есть нам нужно используя утилиту VSCT.exe выполнить примерно такую команду:
"C:\Program Files\Visual Studio 2005 SDK\2007.02\Prerelease\VSCT\VSCT.exe" PkgCmd.cto PkgCmd.vsct -SPkgCmd.ctsym
Команду надо запустить из директории, где находится скомпилированный файл CTO:
<project_root>\obj\Debug\
В противном случае необходимо указывать полные пути до всех файлов-параметров в команде, приведенной выше.
3. Теперь давайте заменим CTC файлы проекта MenuAndCommands на VSCT аналог. Для этого создаем новую папку VSCTComponents в корне проекта и копируем туда только что сгенерированные файлы PkgCmd.vsct из папки obj\Debug\. Затем добавляем новую папку и файл в проект с помощью команды Add Existing Item.. или Include In Project.
Чтобы исключить возможность использования CTC файла давайте удалим все из папки CtcComponents за исключением изображения GenericCmd.bmp, поскольку эта картинка нам еще понадобится. Давайте также внесем заметное визуально отличие и поменяем текст кнопки «C# Command Sample» на «C# Command Sample (VSTS)». Это позволит нам увидеть изменения в меню Tools.

ПРИМЕЧАНИЕ: Вы можете легко добавить возможность IntelliSense для работы c файлами VSCT. Для этого достаточно указать в окне свойств файла (его можно вызвать, нажав F4на клавиатуре) соответствующий XSD файл. А именно в свойстве Schemas укажите путь к файлу схемы:
C:\Program Files\Visual Studio 2005 SDK\2007.02\Prerelease\VSCT\VSCT.xsd
4. Теперь необходимо перестроить проект (Build или Rebuild) и запустить в командной строке Visual Studio (Visual Studio Command Prompt) команду, которая обновит интерфес Visual Studio (разумеется в экспериментальной ветке реестра):
devenv.exe /rootsuffix Exp /setup
После этого жмем F5 для запуска нашего подопытного проекта в экспериментальной ветке реестра. Мы должны увидеть что все команды меню, добавляемые нашим проектом исчезли. Чтобы вернуть их обратно, используя на этот раз формат VSCT, нам необходимо подправить файл проекта - MenuAndCommands.csproj. Для этого нужно выгрузить проект (в Solution Explorer в контекстном меню для проекта выбрать команду Unload) и открыть csproj файл на редактирование (в Solution Explorer в контекстном меню для неактивного узла проекта выбрать команду Edit MenuAndCommands.csproj).

5. В проектный файл необходимо добавить одну строчку, импортирующую MSBuild .targets файл (VSCT_overrides.targets), который я подготовил для вас. Чтобы не вникать в детали MSBuild скрипта Visual Studio, вы можете просто скачать его отсюда и сохранить его в корневой директории проекта.

6. Теперь нам нужно немного подкорректировать то как наш файл PkgCmd.vsct подключен к проекту. Сейчас он должен быть объявлен в файле проекта MenuAndCommands.csproj следующим образом:
<None Include="VSCTComponents\PkgCmd.vsct" />
Замените эту строку следующим кодом (см. рисунок ниже). В дочернем теге ResourceName указывается имя CTO объекта, который будет смерджен с ресурсной сборкой. В данном случае – это 1000.

7. Теперь можно сохранить изменения внесенные в проектный файл MenuAndCommands.csproj и загрузить проект обратно в Solution Explorer (выберите команду Reload в контекстном меню). Поскольку мы добавили импорт на внешний .targets файл, среда разработки выдаст предупреждение (Security Warning dialog). Укажите что проект нужно загрузить обычным образом (выберите опцию Load project normally).
Перекомпилируйте приложение и проверьте результат в окне Output. Вы должны будете увидеть следующие четыре ошибки компиляции VSCT, которые произошли в связи с автоматической перегенерацией.

ПРИМЕЧАНИЕ: убедитесь, что ваша среда разработки достаточно «многословна», то есть настройка ‘MSBuild build output verbosity’ выставлена на обычный уровень (Normal).
8. Для того чтобы исправить упомянутые 4 VSCT ошибки необходимо добавить 4 тега IDSymbols для соответствующих тегов GuidSymbol. Откорректированная версия файла PkgCmd.vsct входит в архив с файлами к этой статье, который я подготовил для вас. Поэтому, Вы можете просто скачать подправленную версию файла PkgCmd.vsct.
После того как 4 тега IDSymbols добавлены необходимо опять перекомпилировать проект и убедиться, что все VSCT ошибки исчезли.

9. Теперь, чтобы увидеть те изменения в среде разработки, которые мы сделали для меню с использованием VSCT формата описания команд, необходимо перекомпилировать все решение и выполнить команду, которая обновит интерфейс Visual Studio:
devenv.exe /rootsuffix Exp /setup
Для запуска среды разработки с новым текстом меню нажмите F5 на клавиатуре и когда Visual Studio запустится, убедитесь что в меню Tools появилась команда с текстом ‘C# Command Sample (VSTS)’.

Вот и все. Оставайтесь на связи!
Ссылки