How do I programmatically list all projects in a solution?

前端 未结 12 1396
感动是毒
感动是毒 2020-11-29 04:06

How do I programmatically list all of the projects in a solution? I\'ll take a script, command-line, or API calls.

相关标签:
12条回答
  • 2020-11-29 04:33

    If you need to do this on a non Windows machine, you can use the following Bash command:

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

    0 讨论(0)
  • 2020-11-29 04:33

    To expand on the answer by @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
            }
    }
    

    This filters to only .csproj files and adds the full path of each based on the File field and the path containing the sln file.

    Use Get-ProjectInSolution MySolution.sln | Select-Object FullName to get each of the full file paths.

    The reason I wanted the full path was to be able to access the packages.config files beside each project file and then get the packages from all of them:

    Get-ProjectInSolution MySolution.sln |
        %{Join-Path ($_.FullName | Split-Path) packages.config} |
        %{select-xml "//package[@id]" $_ | %{$_.Node.GetAttribute("id")}} |
        select -unique
    
    0 讨论(0)
  • 2020-11-29 04:35

    The trick is to choose the right MsBuild.dll. Under VS2017 it is indeed "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\amd64\Microsoft.Build.dll" (Dont use the standard Msbuild ddl in references. Browse to this path)

    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;
         }
      }
    }
    

    powershell:

    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}
        }
    }  
    
    0 讨论(0)
  • 2020-11-29 04:35

    just read the list from *.sln file. There are "Project"-"EndProject" sections.
    Here is an article from MSDN.

    0 讨论(0)
  • 2020-11-29 04:39

    If you write your program as Visual Studio Add-in you can access the EnvDTE to find out all the projects within the currently opened solution.

    0 讨论(0)
  • 2020-11-29 04:42

    Since Visual Studio 2013 the Microsoft.Build.dll provides a SolutionFile object with some very handy functions.

    Here's an example of using the v14.0 version to list the relative path of all the projects in the order they appear in the solution.

    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
    

    There are plenty of other properties on the project object (ProjectName, AbsolutePath, configurations etc) that may be of use. In the above example I used the ProjectType to filter out Solution Folders.

    0 讨论(0)
提交回复
热议问题