internal VsSolutionHierarchyNode(IVsHierarchy hierarchy, uint itemId, Lazy<VsSolutionHierarchyNode> parent) { if (hierarchy == null) throw new ArgumentNullException(nameof(hierarchy), $"{nameof(hierarchy)} is null."); VsHierarchy = hierarchy; ItemId = itemId; 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. int 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); // we are responsible to release the refcount on the out IntPtr parameter if (nestedHierarchy != null) { VsHierarchy = nestedHierarchy; ItemId = nestedItemId; } } DisplayName = VsHierarchy.GetProperty<string>(__VSHPROPID.VSHPROPID_Name, ItemId); m_parent = parent ?? new Lazy<VsSolutionHierarchyNode>(() => { if (VsHierarchy is IVsSolution) return null; var rootHierarchy = hierarchy.GetProperty<IVsHierarchy>(__VSHPROPID.VSHPROPID_ParentHierarchy, VSConstants.VSITEMID_ROOT); if (rootHierarchy == null) return null; var rootNode = new VsSolutionHierarchyNode(rootHierarchy, VSConstants.VSITEMID_ROOT); var parentNode = new VsSolutionHierarchyNode[] { rootNode } .Concat(rootNode.Children.BreadthFirstTraversal(node => node.Children)) .FirstOrDefault(node => node.Children.Any(child => child.ItemId == ItemId)); if (parentNode == null) return null; return new VsSolutionHierarchyNode(parentNode.VsHierarchy, parentNode.ItemId); }); this.m_serviceProvider = new Lazy<IServiceProvider>(() => { Microsoft.VisualStudio.OLE.Interop.IServiceProvider oleSp; hierarchy.GetSite(out oleSp); return oleSp != null ? new ServiceProvider(oleSp) : GlobalVsServiceProvider.Instance; }); }
private void Init(IVsSolution vsSolution, IVsHierarchy vsHierarchy, uint vsItemId) { _solution = vsSolution; int hr; if (vsHierarchy == null) { Guid emptyGuid = Guid.Empty; hr = _solution.GetProjectOfGuid(ref emptyGuid, out _hierarchy); Marshal.ThrowExceptionForHR(hr); } else { _hierarchy = vsHierarchy; } _itemId = vsItemId; 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 convert this node using the inner nestedHierarchy/nestedItemId identity. hr = _hierarchy.GetNestedHierarchy(_itemId, ref hierGuid, out IntPtr nestedHierarchyObj, out uint 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) { _hierarchy = nestedHierarchy; _itemId = nestedItemId; } } }
public ISolutionHierarchyItem CreateSolutionHierarchyItem(IVsHierarchy hierarchy, uint itemId) { Dispatcher.CurrentDispatcher.VerifyAccess(); 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 return(CreateSolutionHierarchyItem(nestedHierarchy, nestedItemId)); } return(null); } else { return(CreateSolutionHierarchyItemDirect(hierarchy, itemId)); } }
/// <summary> /// Process all project hierarchy nodes recursively returning information about the files in them /// </summary> /// <param name="hierarchy">The starting hierarchy node</param> /// <param name="itemId">The item ID</param> /// <param name="projectFiles">The list to which project file information is added</param> private static void ProcessHierarchyNodeRecursively(IVsHierarchy hierarchy, uint itemId, IList <SpellCheckFileInfo> projectFiles) { Microsoft.VisualStudio.Shell.ThreadHelper.ThrowIfNotOnUIThread(); Guid nestedHierarchyGuid; IVsHierarchy nestedHierarchy; IntPtr nestedHierarchyValue = IntPtr.Zero; object value = null; uint visibleChildNode; int result; // First, guess if the node is actually the root of another hierarchy (a project, for example) nestedHierarchyGuid = typeof(IVsHierarchy).GUID; result = hierarchy.GetNestedHierarchy(itemId, ref nestedHierarchyGuid, out nestedHierarchyValue, out uint nestedItemIdValue); if (result == VSConstants.S_OK && nestedHierarchyValue != IntPtr.Zero && nestedItemIdValue == VSConstants.VSITEMID_ROOT) { // Get the new hierarchy nestedHierarchy = System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(nestedHierarchyValue) as IVsHierarchy; System.Runtime.InteropServices.Marshal.Release(nestedHierarchyValue); if (nestedHierarchy != null) { ProcessHierarchyNodeRecursively(nestedHierarchy, VSConstants.VSITEMID_ROOT, projectFiles); } } else { // The node is not the root of another hierarchy, it is a regular node var projectFile = DetermineProjectFileInformation(hierarchy, itemId); if (projectFile != IgnoredHierarchyItem) { if (projectFile != null) { projectFiles.Add(projectFile); } result = hierarchy.GetProperty(itemId, (int)__VSHPROPID.VSHPROPID_FirstVisibleChild, out value); while (result == VSConstants.S_OK && value != null && value is int) { visibleChildNode = (uint)(int)value; if (visibleChildNode == VSConstants.VSITEMID_NIL) { break; } ProcessHierarchyNodeRecursively(hierarchy, visibleChildNode, projectFiles); value = null; result = hierarchy.GetProperty(visibleChildNode, (int)__VSHPROPID.VSHPROPID_NextVisibleSibling, out value); } } } }
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 ProcessHierarchyNodeRecursively(IVsHierarchy hierarchy, uint itemId, ref List <VSITEMEX> hierList) { int result; IntPtr nestedHiearchyValue = IntPtr.Zero; uint nestedItemIdValue = 0; object value = null; uint visibleChildNode; Guid nestedHierarchyGuid; IVsHierarchy nestedHierarchy; // First, guess if the node is actually the root of another hierarchy (a project, for example) nestedHierarchyGuid = typeof(IVsHierarchy).GUID; result = hierarchy.GetNestedHierarchy(itemId, ref nestedHierarchyGuid, out nestedHiearchyValue, out nestedItemIdValue); if (result == VSConstants.S_OK && nestedHiearchyValue != IntPtr.Zero && nestedItemIdValue == VSConstants.VSITEMID_ROOT) { // Get the new hierarchy nestedHierarchy = System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(nestedHiearchyValue) as IVsHierarchy; System.Runtime.InteropServices.Marshal.Release(nestedHiearchyValue); if (nestedHierarchy != null) { ProcessHierarchy(nestedHierarchy, ref hierList); } } else // The node is not the root of another hierarchy, it is a regular node { AddToList(hierarchy, itemId, ref hierList); // Get the first visible child node result = hierarchy.GetProperty(itemId, (int)__VSHPROPID.VSHPROPID_FirstVisibleChild, out value); while (result == VSConstants.S_OK && value != null) { if (value is int && (uint)(int)value == VSConstants.VSITEMID_NIL) { // No more nodes break; } else { visibleChildNode = Convert.ToUInt32(value); // Enter in recursion ProcessHierarchyNodeRecursively(hierarchy, visibleChildNode, ref hierList); // Get the next visible sibling node value = null; result = hierarchy.GetProperty(visibleChildNode, (int)__VSHPROPID.VSHPROPID_NextVisibleSibling, out value); } } } }
internal VsSolutionHierarchyNode(IVsHierarchy hierarchy, uint itemId, Lazy <VsSolutionHierarchyNode> parent) { Guard.NotNull(() => hierarchy, hierarchy); this.VsHierarchy = hierarchy; this.ItemId = itemId; IntPtr nestedHierarchyObj; uint nestedItemId; Guid hierGuid = typeof(IVsHierarchy).GUID; int hr = hierarchy.GetNestedHierarchy(this.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) { this.VsHierarchy = nestedHierarchy; this.ItemId = nestedItemId; } } this.extensibilityObject = new Lazy <object>(() => this.VsHierarchy.Properties(this.ItemId).ExtenderObject); this.serviceProvider = new Lazy <IServiceProvider>(() => { Microsoft.VisualStudio.OLE.Interop.IServiceProvider oleSp; hierarchy.GetSite(out oleSp); return(oleSp != null ? new ServiceProvider(oleSp) : GlobalServiceProvider.Instance); }); this.DisplayName = this.VsHierarchy.Properties(this.ItemId).DisplayName; this.parent = parent ?? new Lazy <VsSolutionHierarchyNode>(() => { if (this.VsHierarchy is IVsSolution) { return(null); } // Implement this property so that it iterates each and every node finding // the parent. var parentItem = this.VsHierarchy.Properties(this.ItemId).Parent; if (parentItem == null) { return(null); } return(new VsSolutionHierarchyNode(parentItem.Hierarchy, parentItem.ItemId)); }); }
/// <include file='doc\FlavoredProject.uex' path='docs/doc[@for="FlavoredProject.GetNestedHierarchy"]/*' /> protected virtual int GetNestedHierarchy(uint itemId, ref System.Guid guidHierarchyNested, out System.IntPtr hierarchyNested, out uint itemIdNested) { if (_innerVsHierarchy != null) { return(_innerVsHierarchy.GetNestedHierarchy(itemId, ref guidHierarchyNested, out hierarchyNested, out itemIdNested)); } else { hierarchyNested = IntPtr.Zero; itemIdNested = VSConstants.VSITEMID_NIL; return(VSConstants.E_NOINTERFACE); } }
private void CollapseHierarchyItems(IVsUIHierarchyWindow toolWindow, IVsHierarchy hierarchy, uint itemid, bool hierIsSolution , string[] captions) { IntPtr ptr; uint num2; Guid gUID = typeof(IVsHierarchy).GUID; if ((hierarchy.GetNestedHierarchy(itemid, ref gUID, out ptr, out num2) == 0) && (IntPtr.Zero != ptr)) { IVsHierarchy objectForIUnknown = Marshal.GetObjectForIUnknown(ptr) as IVsHierarchy; Marshal.Release(ptr); if (objectForIUnknown != null) { this.CollapseHierarchyItems(toolWindow, objectForIUnknown, num2, false, captions); } } else { object obj2; if (!hierIsSolution) { string canonicalname; object captionobj; hierarchy.GetProperty(itemid, (int)__VSHPROPID.VSHPROPID_Caption, out captionobj); var caption = (string)captionobj; if (captions.Contains(caption)) { hierarchy.GetCanonicalName(itemid, out canonicalname); ErrorHandler.ThrowOnFailure(toolWindow.ExpandItem(hierarchy as IVsUIHierarchy, itemid, EXPANDFLAGS.EXPF_CollapseFolder)); } } if (hierarchy.GetProperty(itemid, (int)__VSHPROPID.VSHPROPID_FirstVisibleChild, out obj2) == 0) { uint itemId = this.GetItemId(obj2); while (itemId != uint.MaxValue) { this.CollapseHierarchyItems(toolWindow, hierarchy, itemId, false, captions); int hr = hierarchy.GetProperty(itemId, (int)__VSHPROPID.VSHPROPID_NextVisibleSibling, out obj2); if (hr == 0) { itemId = this.GetItemId(obj2); } else { ErrorHandler.ThrowOnFailure(hr); return; } } } } }
public static void GetIceBuilderItems(IVsHierarchy h, uint itemId, ref List <String> items) { IntPtr nestedValue = IntPtr.Zero; uint nestedId = 0; Guid nestedGuid = typeof(IVsHierarchy).GUID; int result = h.GetNestedHierarchy(itemId, ref nestedGuid, out nestedValue, out nestedId); if (ErrorHandler.Succeeded(result) && nestedValue != IntPtr.Zero && nestedId == VSConstants.VSITEMID_ROOT) { // Get the nested hierachy IVsProject project = System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(nestedValue) as IVsProject; System.Runtime.InteropServices.Marshal.Release(nestedValue); if (project != null) { GetIceBuilderItems(project as IVsHierarchy, VSConstants.VSITEMID_ROOT, ref items); } } else { // Get the first visible child node object value; result = h.GetProperty(itemId, (int)__VSHPROPID.VSHPROPID_FirstVisibleChild, out value); while (result == VSConstants.S_OK && value != null) { if (value is int && (uint)(int)value == VSConstants.VSITEMID_NIL) { // No more nodes break; } else { uint child = Convert.ToUInt32(value); value = null; result = h.GetProperty(child, (int)__VSHPROPID.VSHPROPID_Name, out value); String path = value as String; if (ProjectUtil.IsSliceFileName(path)) { items.Add(path); } GetIceBuilderItems(h, child, ref items); // Get the next visible sibling node value = null; result = h.GetProperty(child, (int)__VSHPROPID.VSHPROPID_NextVisibleSibling, out value); } } } }
internal VsSolutionHierarchyNode(IVsHierarchy hierarchy, uint itemId, Lazy<VsSolutionHierarchyNode> parent) { Guard.NotNull(() => hierarchy, hierarchy); this.VsHierarchy = hierarchy; this.ItemId = itemId; IntPtr nestedHierarchyObj; uint nestedItemId; Guid hierGuid = typeof(IVsHierarchy).GUID; int hr = hierarchy.GetNestedHierarchy(this.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) { this.VsHierarchy = nestedHierarchy; this.ItemId = nestedItemId; } } this.extensibilityObject = new Lazy<object>(() => this.VsHierarchy.Properties(this.ItemId).ExtenderObject); this.serviceProvider = new Lazy<IServiceProvider>(() => { Microsoft.VisualStudio.OLE.Interop.IServiceProvider oleSp; hierarchy.GetSite(out oleSp); return oleSp != null ? new ServiceProvider(oleSp) : GlobalServiceProvider.Instance; }); this.DisplayName = this.VsHierarchy.Properties(this.ItemId).DisplayName; this.parent = parent ?? new Lazy<VsSolutionHierarchyNode>(() => { if (this.VsHierarchy is IVsSolution) return null; // Implement this property so that it iterates each and every node finding // the parent. var parentItem = this.VsHierarchy.Properties(this.ItemId).Parent; if (parentItem == null) return null; return new VsSolutionHierarchyNode(parentItem.Hierarchy, parentItem.ItemId); }); }
private void ParseHierarchy(IVsHierarchy hierarchy, uint itemId) { ThreadHelper.ThrowIfNotOnUIThread(); int result; IntPtr nestedHiearchyValue = IntPtr.Zero; uint nestedItemIdValue = 0; object value = null; uint visibleChildNode; Guid nestedHierarchyGuid; IVsHierarchy nestedHierarchy; nestedHierarchyGuid = typeof(IVsHierarchy).GUID; result = hierarchy.GetNestedHierarchy(itemId, ref nestedHierarchyGuid, out nestedHiearchyValue, out nestedItemIdValue); if (result == VSConstants.S_OK && nestedHiearchyValue != IntPtr.Zero && nestedItemIdValue == (uint)VSConstants.VSITEMID.Root) { nestedHierarchy = System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(nestedHiearchyValue) as IVsHierarchy; System.Runtime.InteropServices.Marshal.Release(nestedHiearchyValue); if (nestedHierarchy != null) { ParseHierarchy(nestedHierarchy, (uint)VSConstants.VSITEMID.Root); } } else { ParseHierarchyItem(hierarchy, itemId); result = hierarchy.GetProperty(itemId, (int)__VSHPROPID.VSHPROPID_FirstChild, out value); while (result == VSConstants.S_OK && value != null) { if (value is int && (VSConstants.VSITEMID)(int) value == VSConstants.VSITEMID.Nil) { break; } visibleChildNode = Convert.ToUInt32(value); ParseHierarchy(hierarchy, visibleChildNode); value = null; result = hierarchy.GetProperty(visibleChildNode, (int)__VSHPROPID.VSHPROPID_NextSibling, out value); } } }
public static Tuple <IVsHierarchy, uint> GetNested(this IVsHierarchy hierarchy, uint itemid) { IntPtr ptr; uint hierId; var guid = typeof(IVsHierarchy).GUID; var hr = hierarchy.GetNestedHierarchy(itemid, ref guid, out ptr, out hierId); if (hr == 0 && ptr != IntPtr.Zero) { var tmp = Marshal.GetObjectForIUnknown(ptr) as IVsHierarchy; Marshal.Release(ptr); if (tmp != null) { return(new Tuple <IVsHierarchy, uint>(tmp, hierId)); } } return(null); }
public static void GetSubProjects(IVsHierarchy h, uint itemId, ref List <IVsProject> projects) { IntPtr nestedValue = IntPtr.Zero; uint nestedId = 0; Guid nestedGuid = typeof(IVsHierarchy).GUID; int result = h.GetNestedHierarchy(itemId, ref nestedGuid, out nestedValue, out nestedId); if (ErrorHandler.Succeeded(result) && nestedValue != IntPtr.Zero && nestedId == VSConstants.VSITEMID_ROOT) { // Get the nested hierachy IVsProject project = System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(nestedValue) as IVsProject; System.Runtime.InteropServices.Marshal.Release(nestedValue); if (project != null) { projects.Add(project); GetSubProjects(project, ref projects); } } }
private void CollapseHierarchyItems(IVsUIHierarchyWindow toolWindow, IVsHierarchy hierarchy, uint itemid, bool hierIsSolution) { ErrorUtilities.VerifyThrowArgumentNull((object)toolWindow, "toolWindow"); ErrorUtilities.VerifyThrowArgumentNull((object)hierarchy, "hierarchy"); Guid guid = typeof(IVsHierarchy).GUID; IntPtr ppHierarchyNested; uint pitemidNested; if (hierarchy.GetNestedHierarchy(itemid, ref guid, out ppHierarchyNested, out pitemidNested) == 0 && IntPtr.Zero != ppHierarchyNested) { IVsHierarchy objectForIunknown = Marshal.GetObjectForIUnknown(ppHierarchyNested) as IVsHierarchy; Marshal.Release(ppHierarchyNested); if (objectForIunknown == null) { return; } this.CollapseHierarchyItems(toolWindow, objectForIunknown, pitemidNested, false); } else { if (!hierIsSolution) { Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(toolWindow.ExpandItem(hierarchy as IVsUIHierarchy, itemid, EXPANDFLAGS.EXPF_CollapseFolder)); } object pvar; if (hierarchy.GetProperty(itemid, -2041, out pvar) != 0) { return; } for (uint itemId = this.GetItemId(pvar); (int)itemId != -1; itemId = this.GetItemId(pvar)) { this.CollapseHierarchyItems(toolWindow, hierarchy, itemId, false); int property = hierarchy.GetProperty(itemId, -2042, out pvar); if (property != 0) { Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(property); break; } } } }
public static IVsHierarchy GetNestedHierarchy(IVsHierarchy hierarchy, uint itemId, out uint nestedItemId) { var iidHierarchyNested = IID_IVsHierarchy; IntPtr ppHierarchyNested; var nestedHierarchy = hierarchy.GetNestedHierarchy(itemId, ref iidHierarchyNested, out ppHierarchyNested, out nestedItemId); IVsHierarchy vsHierarchy = null; try { if (HResult.Succeeded(nestedHierarchy)) { if (ppHierarchyNested != IntPtr.Zero) { vsHierarchy = (IVsHierarchy)Marshal.GetObjectForIUnknown(ppHierarchyNested); } } } finally { TFCommonUtil.SafeRelease(ppHierarchyNested); } return(vsHierarchy); }
/// <summary> /// Enumerates over the hierarchy items for the given hierarchy traversing into nested hierarchies. /// </summary> /// <param name="hierarchy">hierarchy to enmerate over.</param> /// <param name="itemid">item id of the hierarchy</param> /// <param name="recursionLevel">Depth of recursion. e.g. if recursion started with the Solution /// node, then : Level 0 -- Solution node, Level 1 -- children of Solution, etc.</param> /// <param name="hierIsSolution">true if hierarchy is Solution Node. This is needed to special /// case the children of the solution to work around a bug with VSHPROPID_FirstChild and /// VSHPROPID_NextSibling implementation of the Solution.</param> /// <param name="visibleNodesOnly">true if only nodes visible in the Solution Explorer should /// be traversed. false if all project items should be traversed.</param> /// <param name="processNodeFunc">pointer to function that should be processed on each /// node as it is visited in the depth first enumeration.</param> private void EnumHierarchyItems(IVsHierarchy hierarchy, uint itemid, int recursionLevel, bool hierIsSolution, bool visibleNodesOnly) { 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 EnumHierarchyItems(nestedHierarchy, nestedItemId, recursionLevel, false, visibleNodesOnly); } } else { object pVar; // Display name and type of the node in the Output Window ProcessSolutionNode(hierarchy, itemid, recursionLevel); 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, ((visibleNodesOnly || (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) { EnumHierarchyItems(hierarchy, childId, recursionLevel, false, visibleNodesOnly); // 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, ((visibleNodesOnly || (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; } } } } }
public int GetNestedHierarchy(uint itemid, ref Guid iidHierarchyNested, out IntPtr ppHierarchyNested, out uint pitemidNested) { return(_hierarchy.GetNestedHierarchy(itemid, ref iidHierarchyNested, out ppHierarchyNested, out pitemidNested)); }
static void ProcessHierarchyNodeRecursively(IVsHierarchy hierarchy, uint itemId) { int result; IntPtr nestedHiearchyValue = IntPtr.Zero; uint nestedItemIdValue = 0; object value = null; uint visibleChildNode; Guid nestedHierarchyGuid; IVsHierarchy nestedHierarchy; // First, guess if the node is actually the root of another hierarchy (a project, for example) nestedHierarchyGuid = typeof(IVsHierarchy).GUID; result = hierarchy.GetNestedHierarchy(itemId, ref nestedHierarchyGuid, out nestedHiearchyValue, out nestedItemIdValue); if (result == VSConstants.S_OK && nestedHiearchyValue != IntPtr.Zero && nestedItemIdValue == VSConstants.VSITEMID_ROOT) { // Get the new hierarchy nestedHierarchy = System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(nestedHiearchyValue) as IVsHierarchy; System.Runtime.InteropServices.Marshal.Release(nestedHiearchyValue); if (nestedHierarchy != null) { ProcessHierarchy(nestedHierarchy); } } else // The node is not the root of another hierarchy, it is a regular node { ShowNodeName(hierarchy, itemId); // Get the first visible child node result = hierarchy.GetProperty(itemId, (int)__VSHPROPID.VSHPROPID_FirstVisibleChild, out value); while (result == VSConstants.S_OK && value != null) { if (value is int && (uint)(int)value == VSConstants.VSITEMID_NIL) { // No more nodes break; } else { visibleChildNode = Convert.ToUInt32(value); // Enter in recursion ProcessHierarchyNodeRecursively(hierarchy, visibleChildNode); // Get the next visible sibling node value = null; result = hierarchy.GetProperty(visibleChildNode, (int)__VSHPROPID.VSHPROPID_NextVisibleSibling, out value); } } } }
// -------------------------------------------------------------------------------------------- /// <summary> /// Enumerates over the hierarchy items for the given hierarchy traversing into nested /// hierarchies. /// </summary> /// <param name="hierarchy">Hierarchy to enumerate over.</param> /// <param name="itemid">Item id of the hierarchy item to start traversal from.</param> /// <param name="recursionLevel">Depth of recursion. e.g. if recursion started with the Solution /// node, then : Level 0 -- Solution node, Level 1 -- children of Solution, etc.</param> /// <param name="hierIsSolution">true if hierarchy is Solution Node. This is needed to special /// case the children of the solution to work around a bug with VSHPROPID_FirstChild and /// VSHPROPID_NextSibling implementation of the Solution.</param> /// <returns></returns> // -------------------------------------------------------------------------------------------- private static IEnumerable <HierarchyTraversalInfo> TraverseHierarchyItem( IVsHierarchy hierarchy, uint itemid, int recursionLevel, bool hierIsSolution) { IntPtr nestedHierarchyObj; uint nestedItemId; var 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. var hr = hierarchy.GetNestedHierarchy(itemid, ref hierGuid, out nestedHierarchyObj, out nestedItemId); if (VSConstants.S_OK == hr && IntPtr.Zero != nestedHierarchyObj) { var nestedHierarchy = Marshal.GetObjectForIUnknown(nestedHierarchyObj) as IVsHierarchy; Marshal.Release(nestedHierarchyObj); // we are responsible to release the refcount on the out IntPtr parameter if (nestedHierarchy != null) { foreach (var item in TraverseHierarchyItem(nestedHierarchy, nestedItemId, recursionLevel, false)) { yield return(item); } } } else { // --- Return the current hierarchy item yield return(new HierarchyTraversalInfo(hierarchy, itemid, recursionLevel)); 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. object pVar; hr = hierarchy.GetProperty(itemid, (hierIsSolution && recursionLevel == 1) ? (int)__VSHPROPID.VSHPROPID_FirstVisibleChild : (int)__VSHPROPID.VSHPROPID_FirstChild, out pVar); ErrorHandler.ThrowOnFailure(hr); if (VSConstants.S_OK == hr) { // --- We are using DFS so at each level we recurse to check if the node has any // --- children and then look for siblings. var childId = GetItemId(pVar); while (childId != VSConstants.VSITEMID_NIL) { foreach (var item in TraverseHierarchyItem(hierarchy, childId, recursionLevel, false)) { yield return(item); } // --- 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 { ErrorHandler.ThrowOnFailure(hr); break; } } } } }
private IEnumerable <string> TraverseSourceFiles(IVsHierarchy pHierarchy, uint itemid, Stack <string> currentPathes) { var hierGuid = typeof(IVsHierarchy).GUID; PushItemNameToCurrentPathes(pHierarchy, itemid, currentPathes); var hr = pHierarchy.GetNestedHierarchy(itemid, ref hierGuid, out IntPtr nestedHierarchyObj, out uint nestedItemId); if (VSConstants.S_OK == hr && IntPtr.Zero != nestedHierarchyObj) { var nestedHierarchy = Marshal.GetObjectForIUnknown(nestedHierarchyObj) as IVsHierarchy; Marshal.Release(nestedHierarchyObj); if (nestedHierarchy != null) { foreach (var filePath in TraverseSourceFiles(nestedHierarchy, nestedItemId, currentPathes)) { yield return(filePath); } } } else { object pVar; hr = pHierarchy.GetProperty(itemid, (int)__VSHPROPID.VSHPROPID_FirstVisibleChild, out pVar); if (VSConstants.S_OK == hr) { var childId = GetItemId(pVar); if (childId == VSConstants.VSITEMID_NIL) { var itemName = GetItemName(pHierarchy, itemid); if (IsSourceFileName(itemName)) { yield return(GetCurrentFullPath(currentPathes)); } } else { while (childId != VSConstants.VSITEMID_NIL) { foreach (var filePath in TraverseSourceFiles(pHierarchy, childId, currentPathes)) { yield return(filePath); } hr = pHierarchy.GetProperty(childId, (int)__VSHPROPID.VSHPROPID_NextVisibleSibling, out pVar); if (VSConstants.S_OK != hr) { break; } childId = GetItemId(pVar); } } } } currentPathes.Pop(); }
/// <summary> /// Process all project hierarchy nodes recursively returning information about the files in them /// </summary> /// <param name="hierarchy">The starting hierarchy node</param> /// <param name="itemId">The item ID</param> /// <param name="projectFiles">The list to which project file information is added</param> private static void ProcessHierarchyNodeRecursively(IVsHierarchy hierarchy, uint itemId, IList<SpellCheckFileInfo> projectFiles) { int result; IntPtr nestedHiearchyValue = IntPtr.Zero; uint nestedItemIdValue = 0; object value = null; uint visibleChildNode; Guid nestedHierarchyGuid; IVsHierarchy nestedHierarchy; // First, guess if the node is actually the root of another hierarchy (a project, for example) nestedHierarchyGuid = typeof(IVsHierarchy).GUID; result = hierarchy.GetNestedHierarchy(itemId, ref nestedHierarchyGuid, out nestedHiearchyValue, out nestedItemIdValue); if(result == VSConstants.S_OK && nestedHiearchyValue != IntPtr.Zero && nestedItemIdValue == VSConstants.VSITEMID_ROOT) { // Get the new hierarchy nestedHierarchy = System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(nestedHiearchyValue) as IVsHierarchy; System.Runtime.InteropServices.Marshal.Release(nestedHiearchyValue); if(nestedHierarchy != null) ProcessHierarchyNodeRecursively(nestedHierarchy, VSConstants.VSITEMID_ROOT, projectFiles); } else { // The node is not the root of another hierarchy, it is a regular node var projectFile = DetermineProjectFileInformation(hierarchy, itemId); if(projectFile != null) projectFiles.Add(projectFile); result = hierarchy.GetProperty(itemId, (int)__VSHPROPID.VSHPROPID_FirstVisibleChild, out value); while(result == VSConstants.S_OK && value != null && value is int) { visibleChildNode = (uint)(int)value; if(visibleChildNode == VSConstants.VSITEMID_NIL) break; ProcessHierarchyNodeRecursively(hierarchy, visibleChildNode, projectFiles); value = null; result = hierarchy.GetProperty(visibleChildNode, (int)__VSHPROPID.VSHPROPID_NextVisibleSibling, out value); } } }
/// <include file='doc\FlavoredProject.uex' path='docs/doc[@for="FlavoredProject.GetNestedHierarchy"]/*' /> protected virtual int GetNestedHierarchy(uint itemId, ref System.Guid guidHierarchyNested, out System.IntPtr hierarchyNested, out uint itemIdNested) { return(innerVsHierarchy.GetNestedHierarchy(itemId, ref guidHierarchyNested, out hierarchyNested, out itemIdNested)); }
private ISolutionHierarchyItem GetSolutionHierarchy(IVsHierarchy hierarchy, uint itemId, bool visibleNodesOnly, ISolutionHierarchyContainerItem solutionNode) { Dispatcher.CurrentDispatcher.VerifyAccess(); 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 return(GetSolutionHierarchy(nestedHierarchy, nestedItemId, visibleNodesOnly, solutionNode)); } return(null); } else { ISolutionHierarchyItem item = CreateSolutionHierarchyItemDirect(hierarchy, itemId); ISolutionHierarchyContainerItem container = item as ISolutionHierarchyContainerItem; if (container != null) { if (solutionNode == null) { solutionNode = container; } IEnumerable <uint> childIds = EnumerateChildIds(hierarchy, itemId, visibleNodesOnly); if (container == solutionNode && solutionNode != null) { childIds = childIds.OrderBy(id => IsSolutionFolder(hierarchy, id) ? 1 : 0); } foreach (uint childId in childIds) { ISolutionHierarchyItem childItem = GetSolutionHierarchy(hierarchy, childId, visibleNodesOnly, solutionNode); if (childItem != null) { container.Children.Add(childItem); // Due to a bug in VS, enumerating the solution node actually returns all projects within the solution, at any depth, // so we need to remove them here if found. if (container != solutionNode) { solutionNode.Children.Remove(childItem.Id); } } } } return(item); } }
// -------------------------------------------------------------------------------------------- /// <summary> /// Enumerates over the hierarchy items for the given hierarchy traversing into nested /// hierarchies. /// </summary> /// <param name="hierarchy">Hierarchy to enumerate over.</param> /// <param name="itemid">Item id of the hierarchy item to start traversal from.</param> /// <param name="recursionLevel">Depth of recursion. e.g. if recursion started with the Solution /// node, then : Level 0 -- Solution node, Level 1 -- children of Solution, etc.</param> /// <param name="hierIsSolution">true if hierarchy is Solution Node. This is needed to special /// case the children of the solution to work around a bug with VSHPROPID_FirstChild and /// VSHPROPID_NextSibling implementation of the Solution.</param> /// <returns></returns> // -------------------------------------------------------------------------------------------- private static IEnumerable<HierarchyTraversalInfo> TraverseHierarchyItem( IVsHierarchy hierarchy, uint itemid, int recursionLevel, bool hierIsSolution) { IntPtr nestedHierarchyObj; uint nestedItemId; var 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. var hr = hierarchy.GetNestedHierarchy(itemid, ref hierGuid, out nestedHierarchyObj, out nestedItemId); if (VSConstants.S_OK == hr && IntPtr.Zero != nestedHierarchyObj) { var nestedHierarchy = Marshal.GetObjectForIUnknown(nestedHierarchyObj) as IVsHierarchy; Marshal.Release(nestedHierarchyObj); // we are responsible to release the refcount on the out IntPtr parameter if (nestedHierarchy != null) { foreach (var item in TraverseHierarchyItem(nestedHierarchy, nestedItemId, recursionLevel, false)) { yield return item; } } } else { // --- Return the current hierarchy item yield return new HierarchyTraversalInfo(hierarchy, itemid, recursionLevel); 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. object pVar; hr = hierarchy.GetProperty(itemid, (hierIsSolution && recursionLevel == 1) ? (int) __VSHPROPID.VSHPROPID_FirstVisibleChild : (int) __VSHPROPID.VSHPROPID_FirstChild, out pVar); ErrorHandler.ThrowOnFailure(hr); if (VSConstants.S_OK == hr) { // --- We are using DFS so at each level we recurse to check if the node has any // --- children and then look for siblings. var childId = GetItemId(pVar); while (childId != VSConstants.VSITEMID_NIL) { foreach (var item in TraverseHierarchyItem(hierarchy, childId, recursionLevel, false)) { yield return item; } // --- 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 { ErrorHandler.ThrowOnFailure(hr); break; } } } } }