public static void EnumHierarchyItems(this IVsHierarchy hierarchy, uint itemid, int recursionLevel, bool isSolution, bool visibleOnly, bool nothrow, ProcessHierarchyNode processNode) { Contract.Requires<ArgumentNullException>(hierarchy != null, "hierarchy"); Contract.Requires<ArgumentNullException>(processNode != null, "processNode"); int hr; IntPtr nestedHierarchyObj; uint nestedItemId; Guid hierGuid = typeof(IVsHierarchy).GUID; hr = hierarchy.GetNestedHierarchy(itemid, ref hierGuid, out nestedHierarchyObj, out nestedItemId); if (hr == VSConstants.S_OK && nestedHierarchyObj != IntPtr.Zero) { IVsHierarchy nestedHierarchy = Marshal.GetObjectForIUnknown(nestedHierarchyObj) as IVsHierarchy; Marshal.Release(nestedHierarchyObj); if (nestedHierarchy != null) { EnumHierarchyItems(nestedHierarchy, nestedItemId, recursionLevel, false, visibleOnly, nothrow, processNode); } } else { object pVar; processNode(hierarchy, itemid, recursionLevel); recursionLevel++; hr = hierarchy.GetProperty(itemid, ((visibleOnly || (isSolution && recursionLevel == 1)) ? (int)__VSHPROPID.VSHPROPID_FirstVisibleChild : (int)__VSHPROPID.VSHPROPID_FirstChild), out pVar); if (!nothrow) ErrorHandler.ThrowOnFailure(hr); if (hr == VSConstants.S_OK) { uint childId = GetItemId(pVar); while (childId != VSConstants.VSITEMID_NIL) { EnumHierarchyItems(hierarchy, childId, recursionLevel, false, visibleOnly, nothrow, processNode); hr = hierarchy.GetProperty(childId, ((visibleOnly || (isSolution && recursionLevel == 1)) ? (int)__VSHPROPID.VSHPROPID_NextVisibleSibling : (int)__VSHPROPID.VSHPROPID_NextSibling), out pVar); if (!nothrow) ErrorHandler.ThrowOnFailure(hr); if (hr == VSConstants.S_OK) { childId = GetItemId(pVar); } else { childId = VSConstants.VSITEMID_NIL; } } } } }
private static bool EnumHierarchyItems(IVsHierarchy hierarchy, uint itemid, int recursionLevel, bool hierIsSolution, ProcessHierarchyNode processNodeFunc) { int hr; IntPtr nestedHierarchyObj; uint nestedItemId; Guid hierGuid = typeof(IVsHierarchy).GUID; // Check first if this node has a nested hierarchy. If so, then there really are two // identities for this node: 1. hierarchy/itemid 2. nestedHierarchy/nestedItemId. // We will recurse and call EnumHierarchyItems which will display this node using // the inner nestedHierarchy/nestedItemId identity. hr = hierarchy.GetNestedHierarchy(itemid, ref hierGuid, out nestedHierarchyObj, out nestedItemId); if(VSConstants.S_OK == hr && IntPtr.Zero != nestedHierarchyObj) { IVsHierarchy nestedHierarchy = Marshal.GetObjectForIUnknown(nestedHierarchyObj) as IVsHierarchy; Marshal.Release(nestedHierarchyObj); // we are responsible to release the refcount on the out IntPtr parameter if(nestedHierarchy != null) { // Display name and type of the node in the Output Window if (!EnumHierarchyItems(nestedHierarchy, nestedItemId, recursionLevel, false, processNodeFunc)) { return false; } } } else { object pVar; // Display name and type of the node in the Output Window if (!processNodeFunc(hierarchy, itemid, recursionLevel)) { return false; } recursionLevel++; //Get the first child node of the current hierarchy being walked // NOTE: to work around a bug with the Solution implementation of VSHPROPID_FirstChild, // we keep track of the recursion level. If we are asking for the first child under // the Solution, we use VSHPROPID_FirstVisibleChild instead of _FirstChild. // In VS 2005 and earlier, the Solution improperly enumerates all nested projects // in the Solution (at any depth) as if they are immediate children of the Solution. // Its implementation _FirstVisibleChild is correct however, and given that there is // not a feature to hide a SolutionFolder or a Project, thus _FirstVisibleChild is // expected to return the identical results as _FirstChild. hr = hierarchy.GetProperty(itemid, (((hierIsSolution && recursionLevel == 1) ? (int)__VSHPROPID.VSHPROPID_FirstVisibleChild : (int)__VSHPROPID.VSHPROPID_FirstChild)), out pVar); Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(hr); if(VSConstants.S_OK == hr) { //We are using Depth first search so at each level we recurse to check if the node has any children // and then look for siblings. uint childId = GetItemId(pVar); while(childId != VSConstants.VSITEMID_NIL) { if (!EnumHierarchyItems(hierarchy, childId, recursionLevel, false, processNodeFunc)) { return false; } // NOTE: to work around a bug with the Solution implementation of VSHPROPID_NextSibling, // we keep track of the recursion level. If we are asking for the next sibling under // the Solution, we use VSHPROPID_NextVisibleSibling instead of _NextSibling. // In VS 2005 and earlier, the Solution improperly enumerates all nested projects // in the Solution (at any depth) as if they are immediate children of the Solution. // Its implementation _NextVisibleSibling is correct however, and given that there is // not a feature to hide a SolutionFolder or a Project, thus _NextVisibleSibling is // expected to return the identical results as _NextSibling. hr = hierarchy.GetProperty(childId, (((hierIsSolution && recursionLevel == 1)) ? (int)__VSHPROPID.VSHPROPID_NextVisibleSibling : (int)__VSHPROPID.VSHPROPID_NextSibling), out pVar); if(VSConstants.S_OK == hr) { childId = GetItemId(pVar); } else { Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(hr); break; } } } } return true; }
public static void EnumHierarchyItems(this IVsHierarchy hierarchy, uint itemid, int recursionLevel, bool isSolution, bool visibleOnly, ProcessHierarchyNode processNode) { Contract.Requires(hierarchy != null); Contract.Requires(processNode != null); EnumHierarchyItems(hierarchy, itemid, recursionLevel, isSolution, visibleOnly, false, processNode); }
/// <summary> /// Returns a list of Hierarchy items /// </summary> public static void EnumHierarchyItems(IVsSolution solution, ProcessHierarchyNode func) { if(null != solution) { IVsHierarchy solutionHierarchy = solution as IVsHierarchy; if(null != solutionHierarchy) { EnumHierarchyItems(solutionHierarchy, VSConstants.VSITEMID_ROOT, 0, true, func); } } }
/// <summary> /// Returns a list of Hierarchy items /// </summary> public static void EnumHierarchyItems(IVsHierarchy hierarchy, ProcessHierarchyNode func) { if(null != hierarchy) { EnumHierarchyItems(hierarchy, VSConstants.VSITEMID_ROOT, 0, false, func); } }
public static void EnumHierarchyItems(this IVsHierarchy hierarchy, uint itemid, int recursionLevel, bool isSolution, bool visibleOnly, bool nothrow, ProcessHierarchyNode processNode) { Contract.Requires <ArgumentNullException>(hierarchy != null, "hierarchy"); Contract.Requires <ArgumentNullException>(processNode != null, "processNode"); int hr; IntPtr nestedHierarchyObj; uint nestedItemId; Guid hierGuid = typeof(IVsHierarchy).GUID; hr = hierarchy.GetNestedHierarchy(itemid, ref hierGuid, out nestedHierarchyObj, out nestedItemId); if (hr == VSConstants.S_OK && nestedHierarchyObj != IntPtr.Zero) { IVsHierarchy nestedHierarchy = Marshal.GetObjectForIUnknown(nestedHierarchyObj) as IVsHierarchy; Marshal.Release(nestedHierarchyObj); if (nestedHierarchy != null) { EnumHierarchyItems(nestedHierarchy, nestedItemId, recursionLevel, false, visibleOnly, nothrow, processNode); } } else { object pVar; processNode(hierarchy, itemid, recursionLevel); recursionLevel++; hr = hierarchy.GetProperty(itemid, ((visibleOnly || (isSolution && recursionLevel == 1)) ? (int)__VSHPROPID.VSHPROPID_FirstVisibleChild : (int)__VSHPROPID.VSHPROPID_FirstChild), out pVar); if (!nothrow) { ErrorHandler.ThrowOnFailure(hr); } if (hr == VSConstants.S_OK) { uint childId = GetItemId(pVar); while (childId != VSConstants.VSITEMID_NIL) { EnumHierarchyItems(hierarchy, childId, recursionLevel, false, visibleOnly, nothrow, processNode); hr = hierarchy.GetProperty(childId, ((visibleOnly || (isSolution && recursionLevel == 1)) ? (int)__VSHPROPID.VSHPROPID_NextVisibleSibling : (int)__VSHPROPID.VSHPROPID_NextSibling), out pVar); if (!nothrow) { ErrorHandler.ThrowOnFailure(hr); } if (hr == VSConstants.S_OK) { childId = GetItemId(pVar); } else { childId = VSConstants.VSITEMID_NIL; } } } } }
public static void EnumHierarchyItems([NotNull] this IVsHierarchy hierarchy, uint itemid, int recursionLevel, bool isSolution, bool visibleOnly, [NotNull] ProcessHierarchyNode processNode) { Debug.Assert(hierarchy != null); Debug.Assert(processNode != null); EnumHierarchyItems(hierarchy, itemid, recursionLevel, isSolution, visibleOnly, false, processNode); }