代码之家  ›  专栏  ›  技术社区  ›  Kiquenet user385990

如何以编程方式列出解决方案中的所有项目?

  •  36
  • Kiquenet user385990  · 技术社区  · 14 年前

    如何以编程方式列出解决方案中的所有项目?我将使用脚本、命令行或API调用。

    10 回复  |  直到 13 年前
        1
  •  55
  •   brianpeiris    14 年前

    以下是从.sln文件检索项目详细信息的PowerShell脚本:

    Get-Content 'Foo.sln' |
      Select-String 'Project\(' |
        ForEach-Object {
          $projectParts = $_ -Split '[,=]' | ForEach-Object { $_.Trim('[ "{}]') };
          New-Object PSObject -Property @{
            Name = $projectParts[1];
            File = $projectParts[2];
            Guid = $projectParts[3]
          }
        }
    
        2
  •  18
  •   Daniel James Bryars    11 年前
        var Content = File.ReadAllText(SlnPath);
        Regex projReg = new Regex(
            "Project\\(\"\\{[\\w-]*\\}\"\\) = \"([\\w _]*.*)\", \"(.*\\.(cs|vcx|vb)proj)\""
            , RegexOptions.Compiled);
        var matches = projReg.Matches(Content).Cast<Match>();
        var Projects = matches.Select(x => x.Groups[2].Value).ToList();
        for (int i = 0; i < Projects.Count; ++i)
        {
            if (!Path.IsPathRooted(Projects[i]))
                Projects[i] = Path.Combine(Path.GetDirectoryName(SlnPath),
                    Projects[i]);
            Projects[i] = Path.GetFullPath(Projects[i]);
        }
    

    编辑:根据Kumar Vaibhav的评论,修改了正则表达式以包括“.*”

        3
  •  12
  •   PatrickR Scott Mackay    5 年前

    你可以使用环境解决方案项目对象以编程方式获取对解决方案中的项目的访问。

    但有一个问题是,如果您的解决方案中有任何SolutionFolders,那么这些文件夹中的任何项目都不会显示在上面的集合中。

    我写了一篇文章,其中包括一个关于如何 to get all projects 不管任何解决方案文件夹

        4
  •  8
  •   Crono    6 年前

    目前您可以使用 Package Manager Console 以获取信息。使用powershell Get-Project

    Get-Project -All
    
        5
  •  7
  •   Roland Roos    7 年前

    诀窍是选择正确的MsBuild.dll. 在VS2017下,它实际上是“C:\Program Files(x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\amd64\Microsoft.Build.dll" (不要在引用中使用标准Msbuild ddl。浏览到此路径)

    c#:

    var solutionFile =    
    SolutionFile.Parse(@"c:\NuGetApp1\NuGetApp1.sln");//your solution full path name
    var projectsInSolution = solutionFile.ProjectsInOrder;
    foreach(var project in projectsInSolution)
    {
       switch (project.ProjectType)
       {
          case SolutionProjectType.KnownToBeMSBuildFormat:
         {
             break;
         }
         case SolutionProjectType.SolutionFolder:
         {
             break;
         }
      }
    }
    

    Add-Type -Path (${env:ProgramFiles(x86)} + '\Microsoft Visual 
    Studio\2017\Professional\MSBuild\15.0\Bin\amd64\Microsoft.Build.dll')
    
    $slnPath = 'c:\NuGetApp1\NuGetApp1.sln'
    $slnFile = [Microsoft.Build.Construction.SolutionFile]::Parse($slnPath)
    $pjcts = $slnFile.ProjectsInOrder
    
    foreach ($item in $pjcts)
    {
    
        switch($item.ProjectType)
        {
            'KnownToBeMSBuildFormat'{Write-Host Project  : $item.ProjectName}
            'SolutionFolder'{Write-Host Solution Folder : $item.ProjectName}
        }
    }  
    
        6
  •  4
  •   default locale    14 年前

    只需从*.sln文件中读取列表。有“项目”-“结束项目”部分。
    给你 an article from MSDN.

        7
  •  3
  •   Oliver    14 年前

    EnvDTE 查找当前打开的解决方案中的所有项目。

        8
  •  3
  •   akjoshi HCP    7 年前

    Parsing Visual Studio Solution files

    JohnLeidegren的答案是包装内部 Microsoft.Build.Construction.SolutionParser

        9
  •  1
  •   Casey    9 年前

    如果需要在非Windows计算机上执行此操作,可以使用以下Bash命令:

    grep "Project(" NameOfYourSolution.sln | cut -d'"' -f4

        10
  •  1
  •   Adam Hardy    8 年前

    自Visual Studio 2013以来Microsoft.Build.dll提供一个SolutionFile对象,其中包含一些非常方便的函数。

    下面是一个使用v14.0版本的示例,按照它们在解决方案中的出现顺序列出所有项目的相对路径。

    Add-Type -Path (${env:ProgramFiles(x86)} + '\Reference Assemblies\Microsoft\MSBuild\v14.0\Microsoft.Build.dll')
    $solutionFile = '<FULL PATH TO SOLUTION FILE>'
    $solution = [Microsoft.Build.Construction.SolutionFile] $solutionFile
    ($solution.ProjectsInOrder | Where-Object {$_.ProjectType -eq 'KnownToBeMSBuildFormat'}).RelativePath
    

    项目对象上还有很多其他属性(ProjectName、AbsolutePath、configurations等)可以使用。在上面的示例中,我使用ProjectType筛选出解决方案文件夹。

        11
  •  1
  •   Jevgenij Kononov    5 年前

    我想知道的是,这个问题我已经知道了。在运行时,我也在确定这个项目是否是测试项目

    function ReadSolutionFile($solutionName)
    {
        $startTime = (Get-Date).Millisecond
        Write-Host "---------------Read Start---------------" 
        $solutionProjects = @()
    
        dotnet  sln "$solutionName.sln" list | ForEach-Object{     
            if($_  -Match ".csproj" )
            {
                #$projData = ($projectString -split '\\')
    
                $proj = New-Object PSObject -Property @{
    
                    Project = [string]$_;
                    IsTestProject =   If ([string]$_ -Match "test") {$True} Else {$False}  
                }
    
                $solutionProjects += $proj
    
            }
        }
    
        Write-Host "---------------Read finish---------------" 
        $solutionProjects
    
        $finishTime = (Get-Date).Millisecond
        Write-Host "Script run time: $($finishTime-$startTime) mil" 
    }
    

    希望这会有帮助。

        12
  •  0
  •   MattMS    4 年前

    answer 通过 @brianpeiris :

    Function Global:Get-ProjectInSolution {
        [CmdletBinding()] param (
            [Parameter()][string]$Solution
        )
        $SolutionPath = Join-Path (Get-Location) $Solution
        $SolutionFile = Get-Item $SolutionPath
        $SolutionFolder = $SolutionFile.Directory.FullName
    
        Get-Content $Solution |
            Select-String 'Project\(' |
            ForEach-Object {
                $projectParts = $_ -Split '[,=]' | ForEach-Object { $_.Trim('[ "{}]') }
                [PSCustomObject]@{
                    File = $projectParts[2]
                    Guid = $projectParts[3]
                    Name = $projectParts[1]
                }
            } |
            Where-Object File -match "csproj$" |
            ForEach-Object {
                Add-Member -InputObject $_ -NotePropertyName FullName -NotePropertyValue (Join-Path $SolutionFolder $_.File) -PassThru
            }
    }
    

    这只过滤到 .csproj File 字段和包含 sln 文件。

    使用 Get-ProjectInSolution MySolution.sln | Select-Object FullName 获取每个完整的文件路径。

    我想要完整路径的原因是能够访问 packages.config 每个项目文件旁边的文件,然后从所有项目文件中获取包:

    Get-ProjectInSolution MySolution.sln |
        %{Join-Path ($_.FullName | Split-Path) packages.config} |
        %{select-xml "//package[@id]" $_ | %{$_.Node.GetAttribute("id")}} |
        select -unique