0

我正在开发一个Visual Studio扩展,其中我将元素添加到项目中引用的右键单击(上下文)菜单。这是通过定义与IDM_VS_CTXT_REFERENCE的父母Group完成的。找出在Visual Studio扩展中点击了哪个引用

我想表明,隐藏这取决于被点击的参考菜单元素,所以我定义我的菜单项为OleMenuCommand

if (commandService != null) 
{ 
    var menuCommandID = new CommandID(CommandSet, CommandId); 
    var menuItem = new OleMenuCommand(this.MenuItemCallback, menuCommandID); 

    menuItem.BeforeQueryStatus += (sender, args) => 
    { 
     var button = (OleMenuCommand)sender; 
     button.Visible = this.CommandVisible(); 
    }; 

    commandService.AddCommand(menuItem); 
} 

我实现CommandVisible方法麻烦。比方说,如果参考名称以A开头,我想要显示菜单。我会怎么做?

我觉得自己被困在interop地狱里,瞎猜在任意的id,guids和不存在/不可理解的文档上。

我已成功地挖掘出项目我的引用是为IVsProject有的ID为参考,但调用GetMkDocument回报什么(它的工作原理与项目文件,但不引用)。

我该怎么做?我在哪里可以找到关于如何做到这一点的文档?

+0

GetMkDocument只适用于实际的文档,引用只是一种视觉援助,实际上不是文件。我正在进行一些测试,看看我能否帮助你。 –

+0

工作出现了,但我把它拿到了尽头,关键是要使用使用itemid的IVsHierarchy方法。我认为你在正确的轨道上。 –

回答

3

终于明白了。一旦你有了所选项目的IVsHierarchy和itemid,这行就会在你的参数中得到你想要的名字。

hierarchy.GetProperty(itemid, (int)__VSHPROPID.VSHPROPID_Name, out name); 

全码

object name; 
uint itemid = VSConstants.VSITEMID_NIL; 
IVsMultiItemSelect multiItemSelect = null; 
IntPtr hierarchyPtr = IntPtr.Zero; 
IntPtr selectionContainerPtr = IntPtr.Zero; 
try 
{ 
    var monitorSelection = Package.GetGlobalService(typeof(SVsShellMonitorSelection)) as IVsMonitorSelection; 
    monitorSelection.GetCurrentSelection(out hierarchyPtr, out itemid, out multiItemSelect, out selectionContainerPtr); 
    hierarchy = Marshal.GetObjectForIUnknown(hierarchyPtr) as IVsHierarchy;  
    hierarchy.GetProperty(itemid, (int)__VSHPROPID.VSHPROPID_Name, out name); 
}finally 
{ 
    if (selectionContainerPtr != IntPtr.Zero) 
     Marshal.Release(selectionContainerPtr); 

     if (hierarchyPtr != IntPtr.Zero) 
      Marshal.Release(hierarchyPtr); 
} 
+0

一个重要的注意事项:你需要调用hierachyPtr变量上的Marshal.Release,否则你将泄漏COM引用,并且你有内存泄漏。 –

+0

是的你是正确的,代码是其他代码中的一个片段,所以我忘了包括它。更新。 –

+0

不要忘记使用finally块,以防万一中间有什么东西抛出。 :-( –