【问题标题】:How to get all projects name in a solution?如何在解决方案中获取所有项目名称?
【发布时间】:2013-09-30 19:05:49
【问题描述】:

如何通过 C# 获取解决方案中的所有项目名称? 该解决方案具有控制台项目,其中包含许多 Windows 服务。

我的目标是找到所有项目名称,然后获取项目中的所有 Windows 服务名称。

实施将在同一解决方案的新项目中完成。 谢谢提示。

【问题讨论】:

    标签: c# visual-studio-2012


    【解决方案1】:

    选中此MSDN,它将解决您的问题。

    .sln 文件包含环境使用的基于文本的信息 查找并加载持久数据的名称-值参数和 它引用的项目 VSPackages。当用户打开解决方案时, 环境循环通过 preSolution、Project 和 postSolution .sln 文件中的信息以加载解决方案,项目中的 解决方案,以及附加到解决方案的任何持久信息。

    同时检查EnvDTE : Getting all projects

    还可以查看Thread(感谢 John Leidegren 提供了这么好的答案)

    public class Solution
    {
        //internal class SolutionParser
        //Name: Microsoft.Build.Construction.SolutionParser
        //Assembly: Microsoft.Build, Version=4.0.0.0
    
        static readonly Type s_SolutionParser;
        static readonly PropertyInfo s_SolutionParser_solutionReader;
        static readonly MethodInfo s_SolutionParser_parseSolution;
        static readonly PropertyInfo s_SolutionParser_projects;
    
        static Solution()
        {
            s_SolutionParser = Type.GetType("Microsoft.Build.Construction.SolutionParser, Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", false, false);
            if (s_SolutionParser != null)
            {
                s_SolutionParser_solutionReader = s_SolutionParser.GetProperty("SolutionReader", BindingFlags.NonPublic | BindingFlags.Instance);
                s_SolutionParser_projects = s_SolutionParser.GetProperty("Projects", BindingFlags.NonPublic | BindingFlags.Instance);
                s_SolutionParser_parseSolution = s_SolutionParser.GetMethod("ParseSolution", BindingFlags.NonPublic | BindingFlags.Instance);
            }
        }
    
        public List<SolutionProject> Projects { get; private set; }
    
        public Solution(string solutionFileName)
        {
            if (s_SolutionParser == null)
            {
                throw new InvalidOperationException("Can not find type 'Microsoft.Build.Construction.SolutionParser' are you missing a assembly reference to 'Microsoft.Build.dll'?");
            }
            var solutionParser = s_SolutionParser.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic).First().Invoke(null);
            using (var streamReader = new StreamReader(solutionFileName))
            {
                s_SolutionParser_solutionReader.SetValue(solutionParser, streamReader, null);
                s_SolutionParser_parseSolution.Invoke(solutionParser, null);
            }
            var projects = new List<SolutionProject>();
            var array = (Array)s_SolutionParser_projects.GetValue(solutionParser, null);
            for (int i = 0; i < array.Length; i++)
            {
                projects.Add(new SolutionProject(array.GetValue(i)));
            }
            this.Projects = projects;
        }
    }
    
    [DebuggerDisplay("{ProjectName}, {RelativePath}, {ProjectGuid}")]
    public class SolutionProject
    {
        static readonly Type s_ProjectInSolution;
        static readonly PropertyInfo s_ProjectInSolution_ProjectName;
        static readonly PropertyInfo s_ProjectInSolution_RelativePath;
        static readonly PropertyInfo s_ProjectInSolution_ProjectGuid;
    
        static SolutionProject()
        {
            s_ProjectInSolution = Type.GetType("Microsoft.Build.Construction.ProjectInSolution, Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", false, false);
            if (s_ProjectInSolution != null)
            {
                s_ProjectInSolution_ProjectName = s_ProjectInSolution.GetProperty("ProjectName", BindingFlags.NonPublic | BindingFlags.Instance);
                s_ProjectInSolution_RelativePath = s_ProjectInSolution.GetProperty("RelativePath", BindingFlags.NonPublic | BindingFlags.Instance);
                s_ProjectInSolution_ProjectGuid = s_ProjectInSolution.GetProperty("ProjectGuid", BindingFlags.NonPublic | BindingFlags.Instance);
            }
        }
    
        public string ProjectName { get; private set; }
        public string RelativePath { get; private set; }
        public string ProjectGuid { get; private set; }
    
        public SolutionProject(object solutionProject)
        {
            this.ProjectName = s_ProjectInSolution_ProjectName.GetValue(solutionProject, null) as string;
            this.RelativePath = s_ProjectInSolution_RelativePath.GetValue(solutionProject, null) as string;
            this.ProjectGuid = s_ProjectInSolution_ProjectGuid.GetValue(solutionProject, null) as string;
        }
    }
    

    【讨论】:

    • 要使用线程的解决方案,我必须使用Microsoft.VisualStudio.Shell.Interop。我在 Visual Studio 2012 中找不到它。
    • 它在 Visual Studio 2012 中。检查这个:- msdn.microsoft.com/en-us/library/bb164686.aspx
    • 为什么在您自己的答案中重新发布another StackOverflow answer...即使您确实给予了信任。
    • 我试图使用解决方案文件为我的所有 csproj 获取 AssemblyName。这震动了。这是获取每个“解决方案项目”的完整路径的代码。 System.IO.Path.Combine(System.IO.Path.GetDirectoryName(solutionFileName), currentSolutionProject.RelativePath);
    【解决方案2】:

    使用新的Roslyn API 会更容易

    var workspace=MSBuildWorkspace.Create();
    var solution = workspace.OpenSolutionAsync(solutionPath).Result;
    var projects = solution.Projects;
    foreach(var project in projects)
    {
      //TODO              
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多