Добрый день.
Будем делать расширение Visual Studio, которое встраивает в контекстное меню редактора поле «Create C++ Header #define», при клике на которое генерируется уникальная директива #define (директива позволяет включать header только один раз).
В конечном счете выглядеть это будет следующим образом:

На самом деле обычно это автоматизируется с помощью макросов самой студии ( и вариантов макросов в сети много), но мне приятнее использовать контекстное меню, тем более что создание самого расширения — это дело простое, всю работу сделает VSPackage Builder, нам останется лишь вписать несколько строчек кода в обработчик нажатия элемента меню.
Итак, начнем. Нам потребуется Visual Studio 2010 Pro или старше. Необходимо дополнительно установить Visual Studio 2010 SDK и специальное дополнение VSPackage Builder, максимально облегчающее создание новых расширений.
Создадим новый проект в Visual Studio:
Visual C# -> Extensibility -> VSPackage Builder
Даем проекту имя — я назвала его HeaderDefineCreater.

В открывшемся проекте разместим на дизайнере расширения (файл HeaderDefineCreater.vspackage) все необходимые нам элементы. Начнем с первого элемента — добавим контекстное меню. В его свойствах напротив поля Location выберем размещение — «Context Menu | Editor»

Затем создадим группу Group, одну кнопку (назовем ее CreateHeaderDefineButton) и два коннекта между всеми элементами. На скрине с левой стороны показаны свойства для кнопки. Там все стандартное, разве что следует обратить внимание что кнопка (то есть строка в контекстном меню) будет видима только в редакторе (Visibility Constraints: TextEditor). Что касается шортката, то эти поля можно оставить пустыми, поскольку их можно настроить отдельно при использовании расширения.

Ну вот, все готово. Остало��ь только заполнить обработчик нажатия на элемент контекстного меню.
Автоматически сгенерированный обработчик нажатия выглядит следующим образом:
Заполним обработчик. Существует множество схожих по функциональности макросов для студии, написанные в VB, так что ничего не пришлось выдумывать самой, просто слегка переписала на С#.
Нам осталось лишь заполнить поля в манифесте (добавить иконку, описание и тд. ) и все скомпилировать.

После компиляции мы получим готовое расширение HeaderDefineCreater.vsix.
Устанавливается расширение простым двойным кликом.
Удалить его можно зайдя в Tools->Extension Manager.

Для того, чтобы установить шорткат для расширения, нужно зайти в Tools -> Options -> Keyboard, найти там по поиску имя кнопки (мы кнопку назвали CreateHeaderDefineButton, но, впрочем, для простоты можно было бы ее назвать и именем расширения). Для найденной кнопки ставим любое свободное сочетание:

Спасибо за внимание. Замечания приветствуются. Замечу, что я не пишу на C#, а изучаю С++ и расширение создавалось прежд�� всего для облегчения рутинных операций на плюсах и для внутреннего использования. Думаю, что название для поля контекстного меню можно было бы придумать и лучше… да и иконка не соответствует содержимому :) Но здесь мне просто хотелось показать как быстро создать свое расширение, надеюсь, еще кому-нибудь будет полезно.
Я не стала выкладывать сюда весь проект, поскольку расширение очень простое, все шаги описаны, да и весь код в обработчике клика тоже здесь выложен. Поэтому приложу для примера только само расширение, получившееся в итоге — HeaderDefineCreater.vsix
Будем делать расширение Visual Studio, которое встраивает в контекстное меню редактора поле «Create C++ Header #define», при клике на которое генерируется уникальная директива #define (директива позволяет включать header только один раз).
В конечном счете выглядеть это будет следующим образом:

На самом деле обычно это автоматизируется с помощью макросов самой студии ( и вариантов макросов в сети много), но мне приятнее использовать контекстное меню, тем более что создание самого расширения — это дело простое, всю работу сделает VSPackage Builder, нам останется лишь вписать несколько строчек кода в обработчик нажатия элемента меню.
Итак, начнем. Нам потребуется Visual Studio 2010 Pro или старше. Необходимо дополнительно установить Visual Studio 2010 SDK и специальное дополнение VSPackage Builder, максимально облегчающее создание новых расширений.
Создание расширения
Создадим новый проект в Visual Studio:
Visual C# -> Extensibility -> VSPackage Builder
Даем проекту имя — я назвала его HeaderDefineCreater.

В открывшемся проекте разместим на дизайнере расширения (файл HeaderDefineCreater.vspackage) все необходимые нам элементы. Начнем с первого элемента — добавим контекстное меню. В его свойствах напротив поля Location выберем размещение — «Context Menu | Editor»

Затем создадим группу Group, одну кнопку (назовем ее CreateHeaderDefineButton) и два коннекта между всеми элементами. На скрине с левой стороны показаны свойства для кнопки. Там все стандартное, разве что следует обратить внимание что кнопка (то есть строка в контекстном меню) будет видима только в редакторе (Visibility Constraints: TextEditor). Что касается шортката, то эти поля можно оставить пустыми, поскольку их можно настроить отдельно при использовании расширения.

Ну вот, все готово. Остало��ь только заполнить обработчик нажатия на элемент контекстного меню.
Автоматически сгенерированный обработчик нажатия выглядит следующим образом:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell;
namespace HeaderDefineCreater
{
[Guid(GuidList.guidHeaderDefineCreaterPkgString)]
public class HeaderDefineCreaterPackage : HeaderDefineCreaterPackageBase
{
protected override void CreateHeaderDefineButtonExecuteHandler(object sender, EventArgs e)
{
}
}
}
Заполним обработчик. Существует множество схожих по функциональности макросов для студии, написанные в VB, так что ничего не пришлось выдумывать самой, просто слегка переписала на С#.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell;
// Импортируем еще 3 пространства имен:
using System.Windows.Forms;
using EnvDTE;
using System.IO;
namespace HeaderDefineCreater
{
[Guid(GuidList.guidHeaderDefineCreaterPkgString)]
public class HeaderDefineCreaterPackage : HeaderDefineCreaterPackageBase
{
protected override void CreateHeaderDefineButtonExecuteHandler(object sender, EventArgs e)
{
try
{
// Получим объект верхнего уровня в объектной модели автоматизации Visual Studio
EnvDTE.DTE dte = (EnvDTE.DTE)GetService(typeof(EnvDTE.DTE));
// Получим название без расширения у активного документа в Visual Studio
String fileName = Path.GetFileNameWithoutExtension(dte.ActiveDocument.Name);
// Приведем название к прописным буквам
fileName = fileName.ToUpper();
// Сгенерируем уникальный идентификатор GUID
String strGuid = System.Guid.NewGuid().ToString().ToUpper();
strGuid = strGuid.Replace("-", "_");
// Объединим название файла и идентификатор GUID
String strDefine = fileName + "_" + strGuid;
// Создадим саму надпись, которая будет выведена в документе
string txt = "";
txt += "\n#ifndef " + strDefine;
txt += "\n#define " + strDefine;
txt += "\n\n\n\n\n#endif // " + strDefine;
txt += "\n";
// Выведем надпись в активный документ
TextSelection textSelection = (TextSelection)dte.ActiveDocument.Selection;
textSelection.Text = txt;
}
catch (Exception ex)
{
// Если что-то пошло не так, то просто покажем сообщение об ошибке и не уроним студию...
MessageBox.Show(ex.Message);
}
}
}
}
Нам осталось лишь заполнить поля в манифесте (добавить иконку, описание и тд. ) и все скомпилировать.

После компиляции мы получим готовое расширение HeaderDefineCreater.vsix.
Установка расширения и смена шорткатов
Устанавливается расширение простым двойным кликом.
Удалить его можно зайдя в Tools->Extension Manager.

Для того, чтобы установить шорткат для расширения, нужно зайти в Tools -> Options -> Keyboard, найти там по поиску имя кнопки (мы кнопку назвали CreateHeaderDefineButton, но, впрочем, для простоты можно было бы ее назвать и именем расширения). Для найденной кнопки ставим любое свободное сочетание:

Спасибо за внимание. Замечания приветствуются. Замечу, что я не пишу на C#, а изучаю С++ и расширение создавалось прежд�� всего для облегчения рутинных операций на плюсах и для внутреннего использования. Думаю, что название для поля контекстного меню можно было бы придумать и лучше… да и иконка не соответствует содержимому :) Но здесь мне просто хотелось показать как быстро создать свое расширение, надеюсь, еще кому-нибудь будет полезно.
Я не стала выкладывать сюда весь проект, поскольку расширение очень простое, все шаги описаны, да и весь код в обработчике клика тоже здесь выложен. Поэтому приложу для примера только само расширение, получившееся в итоге — HeaderDefineCreater.vsix
