2012-06-15 3 views
5

Я пишу пакет настройки для Visual Studio 2010 (vsix).Выбранный проект из Solution Solution

Что мне нужно сделать, это добавить кнопку контекстного меню к узлам проекта в обозревателе решений.

Мне удалось отобразить контекстное меню при щелчке правой кнопкой мыши по узлам проекта, но моя следующая задача - получить ссылку на объект проекта, который был нажат. В настоящее время я могу получить проект, пройдя активный документ в среде IDE, используя приведенный ниже код.

DTE dte = (DTE)ServiceProvider.GlobalProvider.GetService(typeof(DTE)); 
Project project = dte.ActiveDocument.ProjectItem.ContainingProject; 

Так что мой вопрос: как получить аналогичную ссылку на проект, выбранный в обозревателе решений?

ответ

11

Я понял. Можно также поделиться информацией.

С помощью сервиса SVsShellMonitorSelection я могу получить ссылку на выбранную иерархию как IVsHierarchy, что, в свою очередь, позволяет мне получить ссылку на выбранный объект. Затем это можно отнести к классам, таким как Project, ProjectItem и т. Д., В зависимости от того, что выбрано в обозревателе решений. Handy!

IntPtr hierarchyPointer, selectionContainerPointer; 
Object selectedObject = null; 
IVsMultiItemSelect multiItemSelect; 
uint projectItemId; 

IVsMonitorSelection monitorSelection = 
     (IVsMonitorSelection)Package.GetGlobalService(
     typeof(SVsShellMonitorSelection)); 

monitorSelection.GetCurrentSelection(out hierarchyPointer, 
            out projectItemId, 
            out multiItemSelect, 
            out selectionContainerPointer); 

IVsHierarchy selectedHierarchy = Marshal.GetTypedObjectForIUnknown(
            hierarchyPointer, 
            typeof(IVsHierarchy)) as IVsHierarchy; 

if (selectedHierarchy != null) 
{ 
    ErrorHandler.ThrowOnFailure(selectedHierarchy.GetProperty(
             projectItemId, 
             (int)__VSHPROPID.VSHPROPID_ExtObject, 
             out selectedObject)); 
} 

Project selectedProject = selectedObject as Project; 

Here's the source

+0

Я так счастлив, что нашел это, не мог найти где-нибудь еще, как это сделать. : D – bio595

+1

Я думаю, что вам не хватает 'Marshal.Release (hierarchyPtr); Marshal.Release (selectionContainerPointer); 'в конце, чтобы избежать утечки памяти. В противном случае отлично! – MickyD

+0

Это может быть очевидно, но, как начинающий пользователь IntPtr, стоит отметить, что вы можете проверить selectContainerPointer == IntPtr.Zero перед вызовом Marshal.Release на нем, чтобы исключить исключение нулевого указателя. – webjprgm