本文介绍了如何使用 EnvDTE 列出当前解决方案中的所有项目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在关注

我的解决方案资源管理器看起来像:

更新:来自 gitter/extendvs 的 Bert Huijben 提出以下建议,可在 Extensibility-Samples="Extensibility-Samples"示例# - 但这也不起作用(在构造函数和回调函数中返回 0 个元素):

私有哈希表 GetLoadedControllableProjectsEnum(){Hashtable mapHierarchies = new Hashtable();IVsSolution sol = (IVsSolution)this.ServiceProvider.GetService(typeof(SVsSolution));Guid rguidEnumOnlyThisType = new Guid();IEnumHierarchies ppenum = null;ErrorHandler.ThrowOnFailure(sol.GetProjectEnum((uint)__VSENUMPROJFLAGS.EPF_LOADEDINSOLUTION, ref rguidEnumOnlyThisType, out ppenum));IVsHierarchy[] rgelt = 新的 IVsHierarchy[1];uint pceltFetched = 0;while (ppenum.Next(1, rgelt, out pceltFetched) == VSConstants.S_OK &&pceltFetched == 1){IVsSccProject2 sccProject2 = rgelt[0] 作为 IVsSccProject2;如果 (sccProject2 != null){mapHierarchies[rgelt[0]] = true;}}返回 mapHierarchies;}
解决方案

获取 EnvDTE.Project 对象:

 static private void FindProjectsIn(EnvDTE.ProjectItem item, List results){if (item.Object 是 EnvDTE.Project){var proj = (EnvDTE.Project)item.Object;if (new Guid(proj.Kind) != Utilities.ProjectTypeGuids.Folder){结果.Add((EnvDTE.Project)item.Object);}别的{foreach(proj.ProjectItems 中的 EnvDTE.ProjectItem innerItem){FindProjectsIn(innerItem, 结果);}}}if (item.ProjectItems != null){foreach(item.ProjectItems 中的 EnvDTE.ProjectItem innerItem){FindProjectsIn(innerItem, 结果);}}}static private void FindProjectsIn(EnvDTE.UIHierarchyItem item, List results){if (item.Object 是 EnvDTE.Project){var proj = (EnvDTE.Project)item.Object;if (new Guid(proj.Kind) != Utilities.ProjectTypeGuids.Folder){结果.Add((EnvDTE.Project)item.Object);}别的{foreach(proj.ProjectItems 中的 EnvDTE.ProjectItem innerItem){FindProjectsIn(innerItem, 结果);}}}foreach(item.UIHierarchyItems 中的 EnvDTE.UIHierarchyItem innerItem){FindProjectsIn(innerItem, 结果);}}静态内部 IEnumerableGetEnvDTEProjectsInSolution(){列表ret = new List();EnvDTE80.DTE2 dte = (EnvDTE80.DTE2)ServiceProvider.GlobalProvider.GetService(typeof(EnvDTE.DTE));EnvDTE.UIHierarchy 层次结构 = dte.ToolWindows.SolutionExplorer;foreach (EnvDTE.UIHierarchyItem 在hierarchy.UIHierarchyItems 中的innerItem){FindProjectsIn(innerItem, ret);}返回 ret;}

特别是递归是挖掘解决方案文件夹所必需的.

如果你只想要文件路径,你可以不使用 DTE 来做到这一点:

 静态内部字符串[] GetProjectFilesInSolution(){IVsSolution sol = ServiceProvider.GlobalProvider.GetService(typeof(SVsSolution)) 作为 IVsSolution;uint numProjects;ErrorHandler.ThrowOnFailure(sol.GetProjectFilesInSolution((uint)__VSGETPROJFILESFLAGS.GPFF_SKIPUNLOADEDPROJECTS, 0, null, out numProjects));字符串[] 项目 = 新字符串[numProjects];ErrorHandler.ThrowOnFailure(sol.GetProjectFilesInSolution((uint)__VSGETPROJFILESFLAGS.GPFF_SKIPUNLOADEDPROJECTS, numProjects, projects, out numProjects));//GetProjectFilesInSolution 也返回解决方案文件夹,所以我们要做一些过滤//磁盘上不存在的东西肯定不能是项目文件return projects.Where(p => !string.IsNullOrEmpty(p) && System.IO.File.Exists(p)).ToArray();}

I've been following MSDN's Hello World guide to developing Visual Studio extensions (this article specifically deals with creating one as a Visual Studio toolbar command).

I am trying to list all projects contained in the current/active solution.

In the auto generated code for the Command template.

I have tried EnvDTE's Solution's Projects property, but it shows zero projects.

There is a ActiveSolutionProjects property as well, but it also shows an empty array.

How is this achieved ?

P.S.: I tried both DTE and DTE2 interfaces since it is confusing understanding which version to use, from the docs. I get a null service for DTE2, so I am going with DTE.

My Solution Explorer looks like:


Update: Bert Huijben, from gitter/extendvs, suggested the following, found at the VSSDK Extensibility Samples - but this too does not work (returns 0 elements, both within the constructor and within the callback function):

private Hashtable GetLoadedControllableProjectsEnum()
{
    Hashtable mapHierarchies = new Hashtable();

    IVsSolution sol = (IVsSolution)this.ServiceProvider.GetService(typeof(SVsSolution));
    Guid rguidEnumOnlyThisType = new Guid();
    IEnumHierarchies ppenum = null;
    ErrorHandler.ThrowOnFailure(sol.GetProjectEnum((uint)__VSENUMPROJFLAGS.EPF_LOADEDINSOLUTION, ref rguidEnumOnlyThisType, out ppenum));

    IVsHierarchy[] rgelt = new IVsHierarchy[1];
    uint pceltFetched = 0;
    while (ppenum.Next(1, rgelt, out pceltFetched) == VSConstants.S_OK &&
           pceltFetched == 1)
    {
        IVsSccProject2 sccProject2 = rgelt[0] as IVsSccProject2;
        if (sccProject2 != null)
        {
            mapHierarchies[rgelt[0]] = true;
        }
    }

    return mapHierarchies;
}
解决方案

To get the EnvDTE.Project objects:

    static private void FindProjectsIn(EnvDTE.ProjectItem item, List<EnvDTE.Project> results)
    {
        if (item.Object is EnvDTE.Project)
        {
            var proj = (EnvDTE.Project)item.Object;
            if (new Guid(proj.Kind) != Utilities.ProjectTypeGuids.Folder)
            {
                results.Add((EnvDTE.Project)item.Object);
            }
            else
            {
                foreach (EnvDTE.ProjectItem innerItem in proj.ProjectItems)
                {
                    FindProjectsIn(innerItem, results);
                }
            }
        }
        if (item.ProjectItems != null)
        {
            foreach (EnvDTE.ProjectItem innerItem in item.ProjectItems)
            {
                FindProjectsIn(innerItem, results);
            }
        }
    }

    static private void FindProjectsIn(EnvDTE.UIHierarchyItem item, List<EnvDTE.Project> results)
    {
        if (item.Object is EnvDTE.Project)
        {
            var proj = (EnvDTE.Project)item.Object;
            if (new Guid(proj.Kind) != Utilities.ProjectTypeGuids.Folder)
            {
                results.Add((EnvDTE.Project)item.Object);
            }
            else
            {
                foreach (EnvDTE.ProjectItem innerItem in proj.ProjectItems)
                {
                    FindProjectsIn(innerItem, results);
                }
            }
        }
        foreach (EnvDTE.UIHierarchyItem innerItem in item.UIHierarchyItems)
        {
            FindProjectsIn(innerItem, results);
        }
    }

    static internal IEnumerable<EnvDTE.Project> GetEnvDTEProjectsInSolution()
    {
        List<EnvDTE.Project> ret = new List<EnvDTE.Project>();
        EnvDTE80.DTE2 dte = (EnvDTE80.DTE2)ServiceProvider.GlobalProvider.GetService(typeof(EnvDTE.DTE));
        EnvDTE.UIHierarchy hierarchy = dte.ToolWindows.SolutionExplorer;
        foreach (EnvDTE.UIHierarchyItem innerItem in hierarchy.UIHierarchyItems)
        {
            FindProjectsIn(innerItem, ret);
        }
        return ret;
    }

Notably recursion is necessary to dig into solution folders.

If you just want the file paths you can do this w/o using DTE:

    static internal string[] GetProjectFilesInSolution()
    {
        IVsSolution sol = ServiceProvider.GlobalProvider.GetService(typeof(SVsSolution)) as IVsSolution;
        uint numProjects;
        ErrorHandler.ThrowOnFailure(sol.GetProjectFilesInSolution((uint)__VSGETPROJFILESFLAGS.GPFF_SKIPUNLOADEDPROJECTS, 0, null, out numProjects));
        string[] projects = new string[numProjects];
        ErrorHandler.ThrowOnFailure(sol.GetProjectFilesInSolution((uint)__VSGETPROJFILESFLAGS.GPFF_SKIPUNLOADEDPROJECTS, numProjects, projects, out numProjects));
        //GetProjectFilesInSolution also returns solution folders, so we want to do some filtering
        //things that don't exist on disk certainly can't be project files
        return projects.Where(p => !string.IsNullOrEmpty(p) && System.IO.File.Exists(p)).ToArray();
    }

这篇关于如何使用 EnvDTE 列出当前解决方案中的所有项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-13 01:29