web-dev-qa-db-fra.com

Comment répertorier par programme tous les projets d'une solution?

Comment répertorier par programme tous les projets d'une solution? Je prendrai un script, une ligne de commande ou des appels d'API.

44
Kiquenet

Voici un script PowerShell qui récupère les détails du projet à partir d'un fichier .sln:

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]
      }
    }
53
brianpeiris
    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]);
    }

Edit: modification de l'expression régulière pour inclure le ". *" Selon le commentaire de Kumar Vaibhav

17
watbywbarif

Vous pouvez utiliser l'objet EnvDTE.Solution.Projects pour accéder par programme aux projets d'une solution.

Un problème est que si vous avez des dossiers Solution dans votre solution, tous les projets dans ces dossiers ne sont pas affichés dans la collection ci-dessus.

J'ai écrit un article comprenant un exemple de code sur la façon dont pour obtenir tous les projets quels que soient les dossiers de solution

11
Scott Mackay

L'astuce consiste à choisir le bon MsBuild.dll. Sous VS2017, il s'agit en effet de "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\AMD64\Microsoft.Build.dll" (n'utilisez pas le ddl Msbuild standard dans les références. Recherchez chemin)

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}
    }
}  
7
Roland Roos

Actuellement, vous pouvez utiliser Package Manager Console dans VS pour obtenir ces informations. Utilisez PowerShell Get-Project commande

Get-Project -All
7
cezarypiatek

il suffit de lire la liste du fichier * .sln. Il existe des sections "Projet" - "EndProject".
Voici n article de MSDN.

4
default locale

Il y a une solution vraiment élégante ici: Analyse des fichiers de solution Visual Studio

La réponse de John Leidegren consiste à encapsuler la classe interne Microsoft.Build.Construction.SolutionParser.

3
Dylan Berry

Si vous écrivez votre programme en tant que complément Visual Studio, vous pouvez accéder à EnvDTE pour découvrir tous les projets dans la solution actuellement ouverte.

3
Oliver

Depuis Visual Studio 2013, Microsoft.Build.dll fournit un objet SolutionFile avec quelques fonctions très pratiques.

Voici un exemple d'utilisation de la version v14.0 pour répertorier le chemin relatif de tous les projets dans l'ordre dans lequel ils apparaissent dans la 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

Il existe de nombreuses autres propriétés sur l'objet projet (ProjectName, AbsolutePath, configurations, etc.) qui peuvent être utiles. Dans l'exemple ci-dessus, j'ai utilisé le ProjectType pour filtrer les dossiers de solutions.

1
Adam Hardy

Si vous devez le faire sur une machine non Windows, vous pouvez utiliser la commande Bash suivante:

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

1
Casey

Je sais que c'est peut-être déjà répondu à la question, mais je voudrais partager mon approche de la lecture du fichier sln. Aussi pendant la phase d'exécution, je détermine si le projet est un projet de test ou non

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

J'espère que cela vous sera utile.

0
Jevgenij Kononov