Exemple #1
0
        private HierarchyItem CreateItem(string fileName, HierarchyItemType itemType, HierarchyNode node)
        {
            HierarchyItem parent = this.ancestors.Count > 0 ? this.ancestors.Peek() : null;
            var           result = new HierarchyItem(fileName, itemType, node.Caption, parent);

            return(result);
        }
Exemple #2
0
        private HierarchyItem VisitHierarchyNode(HierarchyNode node)
        {
            HierarchyItem result    = null;
            IVsHierarchy  hierarchy = node.Hierarchy;

            Guid itemType = node.ItemType;

            if (itemType == VSConstants.GUID_ItemType_PhysicalFile)
            {
                string canonicalName = node.CanonicalName;
                if (!string.IsNullOrEmpty(canonicalName))
                {
                    result = this.CreateItem(canonicalName, HierarchyItemType.File, node);
                }
            }
            else
            {
                IVsSolution solution = hierarchy as IVsSolution;
                if (solution != null)
                {
                    string directory, file, options;
                    int    hr = solution.GetSolutionInfo(out directory, out file, out options);
                    if (ErrorHandler.Succeeded(hr) && !string.IsNullOrEmpty(directory) && !string.IsNullOrEmpty(file))
                    {
                        result = this.CreateItem(Path.Combine(directory, file), HierarchyItemType.Solution, node);
                    }
                }
                else
                {
                    IVsProject project = hierarchy as IVsProject;
                    if (project != null)
                    {
                        // For some reason, physical folders (like Properties) also implement IVsProject.
                        if (itemType != VSConstants.GUID_ItemType_PhysicalFolder)
                        {
                            string projectFile;
                            int    hr = project.GetMkDocument(node.ItemId, out projectFile);
                            if (ErrorHandler.Succeeded(hr))
                            {
                                result = this.CreateItem(projectFile, HierarchyItemType.Project, node);
                            }
                        }
                    }
                }
            }

            return(result);
        }
Exemple #3
0
        public bool AddHierarchyItem(HierarchyItem item)
        {
            if (this.hierarchyItems == EmptySet)
            {
                this.hierarchyItems = new HashSet <HierarchyItem>();
            }

            bool result = this.hierarchyItems.Add(item);

            if (result)
            {
                this.projectNames = null;
            }

            return(result);
        }
Exemple #4
0
        public HierarchyItem(string fileName, HierarchyItemType itemType, string caption, HierarchyItem parent)
        {
            this.FileName = fileName;
            this.ItemType = itemType;

            // Note: Solution captions can contain the Unicode Left-To-Right Order Mark (0x200E) character.
            // It doesn't hurt anything usually, but it can show up as ? if it's incorrectly decoded.
            this.Caption = caption;
            this.Parent  = parent;
            this.Level   = parent != null ? parent.Level + 1 : 0;
        }
Exemple #5
0
        /// <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</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="visibleNodesOnly">true if only nodes visible in the Solution Explorer should
        /// be traversed. false if all project items should be traversed.</param>
        private void VisitHierarchyNodes(HierarchyNode node, int recursionLevel, bool visibleNodesOnly)
        {
            // Note: This code originated from "Solution Hierarchy Traversal Sample (C#)"
            // https://msdn.microsoft.com/en-us/library/bb165347(v=vs.80).aspx
            // In C:\Setups\Microsoft\Visual Studio\VS 2005\Visual Studio 2005 SDK\ ...
            // VisualStudioIntegration\Samples\Project\CSharp\Example.SolutionHierarchyTraversal
            //
            // Check first if this node has a nested hierarchy. If so, then there really are two
            // identities for this node: 1. hierarchy/itemid and 2. nestedHierarchy/nestedItemId.
            // We will recurse and call VisitHierarchyNodes which will traverse this node using
            // the inner nestedHierarchy/nestedItemId identity.  Basically, if this returns a
            // nested hierarchy, then the current node is just a shortcut to the nested hierarchy.
            HierarchyNode nestedNode;

            if (node.TryGetNestedHierarchy(out nestedNode))
            {
                this.VisitHierarchyNodes(nestedNode, recursionLevel, visibleNodesOnly);
            }
            else
            {
                // In VS 2015 and earlier, the Solution node enumerates ALL projects (including nested projects)
                // when asking for FirstChild/NextSibling, but it doesn't do that for FirstVisibleChild/NextVisibleSibling.
                // VS treats the actual hierarchy differently than the visible hierarchy, and the solution contains
                // shortcuts to all the projects in the actual hierarchy.  So if we're not restricted to visible nodes,
                // then we can encounter nested projects twice as we traverse the hierarchy.  We'll make sure
                // we don't traverse through the same project twice.  However, we can't restrict to visible items
                // because we need to ensure that we get the "Miscellaneous Files" (e.g., external files opened
                // in the solution), which may not be visible in the Solution Explorer.
                //
                // Note: currentItem can be null if we're visiting a physical folder (e.g., a Properties folder), a
                // virtual folder (e.g., Solution Items or Miscellaneous Files), or some other node type that is
                // not a solution, project or file type.
                HierarchyItem currentItem   = this.VisitHierarchyNode(node);
                bool          visitChildren = true;
                if (currentItem != null)
                {
                    visitChildren = currentItem.ItemType != HierarchyItemType.Project || !this.visitedProjects.Contains(currentItem.FileName);
                    if (visitChildren)
                    {
                        this.items.Add(currentItem);
                    }
                }

                if (visitChildren)
                {
                    // Note: We'll push a null parent for miscellaneous files since they're not directly referenced by the solution.
                    bool pushCurrentItemAsAncestor = (currentItem != null && currentItem.IsContainer) ||
                                                     (currentItem == null && node.ItemType == VSConstants.GUID_ItemType_VirtualFolder && node.CanonicalName == "Miscellaneous Files");
                    if (pushCurrentItemAsAncestor)
                    {
                        this.ancestors.Push(currentItem);
                    }

                    try
                    {
                        recursionLevel++;
                        List <HierarchyNode> children = node.GetChildren(visibleNodesOnly).ToList();
                        foreach (HierarchyNode child in children)
                        {
                            this.VisitHierarchyNodes(child, recursionLevel, visibleNodesOnly);
                        }
                    }
                    finally
                    {
                        if (pushCurrentItemAsAncestor)
                        {
                            this.ancestors.Pop();
                        }
                    }

                    if (currentItem != null && currentItem.ItemType == HierarchyItemType.Project)
                    {
                        this.visitedProjects.Add(currentItem.FileName);
                    }
                }
            }
        }