获取嵌套层次结构 returns 无效状态代码

Getting Nested Hierarchy returns invalid status code

基本上我正在尝试获取项目中文件夹的嵌套层次结构。在下方您可以看到我的代码的简化版本,其中我采用层次结构的第一个节点,它是一个文件夹。

CurrentHierarchy.GetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_FirstVisibleChild, out var tempNode);

if (IsFolder)
{
    var guid = typeof(IVsHierarchy).GUID;

    var result = CurrentHierarchy.GetNestedHierarchy((uint)(int)tempNode, ref guid, out var hierarchyObjectPointer, out var nested); // Returns invalid status code

    var hierarchy = (IVsHierarchy)Marshal.GetObjectForIUnknown(hierarchyObjectPointer);
    Marshal.Release(hierarchyObjectPointer);
}

无论如何变量result包含值-2147483648int.MinValue,这当然是无效的。我想知道我在这里做错了什么。我查看了几个网页:GitHub 1, GitHub 2 and Hot Examples,但它们似乎与我所做的相同。

请注意,CurrentHierarchy 代表项目层次结构,IsFolder 的值实际上是正确的,例如节点实际上是一个文件夹。


编辑

在进一步挖掘之后,我注意到 GetNestedHierarchy 实际上正在返回 VSConstants.E_FAIL,这意味着:

If the requested interface is not supported on the hierarchy object, Microsoft.VisualStudio.VSConstants.E_NOINTERFACE is returned. The caller would then treat this node as if it had no children, if the requested interface had been essential (as is often the case when the requested interface is IID_IVsUIHierarchy).

这甚至让我更加困惑,因为我传递给该方法的节点确实是一个文件夹。


编辑 2

如果 IVsHierarchy 表示 IVsSolution,代码似乎工作正常,但是一旦我尝试获取嵌套层次结构的嵌套层次结构,它就不再工作了.

我想我可以在以下几点中为您提供答案:

在此处设置断点:

var result = CurrentHierarchy.GetNestedHierarchy((uint)(int)tempNode, ref guid, out var hierarchyObjectPointer, out var nested); // Returns invalid status code

然后:

  1. 检查 CurrentHierarchy 对象以确保它具有非空的 FirstChild 属性 值。如果它为空,您将获得 VSConstants.E_FAIL 的 return 值。

  2. 检查 ID 值等于您传入的 uint tempNode 值的节点的整个层次结构。如果没有节点 ID 与 tempNode 值匹配,则获取 return 值VSConstants.E_FAIL.

以上有帮助吗?

这整个事情实际上比最初预期的要容易得多。我实际上想念 GetNestedHierarchy 的用法和整个原理。那我就给大家解释一下吧。

乍一看,您可能认为文件夹和任何可扩展的节点都是层次结构,但不是!

什么是层次结构?实际上,根据我的测试,层次结构只有一个 Solution 和一个 Projectnothing 其他。因此,如果您想在项目的文件夹中获取一个项目,您需要通过一遍又一遍地调用 GetProperty 来获取每个子项。

hierarchy.GetProperty(folderItemId, (int)__VSHPROPID.VSHPROPID_FirstChild, out var folderItem);
hierarchy.GetProperty(folderItem, (int)__VSHPROPID.VSHPROPID_FirstChild, out var folderItemItem);

基本上项目 IVsHierarchy 包含项目中的 所有 项目。