C# 如何以编程方式列出解决方案中的所有项目?
如何以编程方式列出解决方案中的所有项目?我将使用脚本、命令行或API调用。只需从*.sln文件中读取列表。有“项目”-“结束项目”部分。C# 如何以编程方式列出解决方案中的所有项目?,c#,visual-studio-2008,scripting,projects-and-solutions,C#,Visual Studio 2008,Scripting,Projects And Solutions,如何以编程方式列出解决方案中的所有项目?我将使用脚本、命令行或API调用。只需从*.sln文件中读取列表。有“项目”-“结束项目”部分。 以下是如果您以Visual Studio加载项的形式编写程序,则可以访问以查找当前打开的解决方案中的所有项目。以下是从.sln文件检索项目详细信息的PowerShell脚本: Get-Content 'Foo.sln' | Select-String 'Project\(' | ForEach-Object { $projectPart
以下是如果您以Visual Studio加载项的形式编写程序,则可以访问以查找当前打开的解决方案中的所有项目。以下是从.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]
}
}
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
您可以使用EnvDTE.Solution.Projects对象以编程方式访问解决方案中的项目
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
但有一个问题是,如果您的解决方案中有任何SolutionFolders,则这些文件夹中的任何项目都不会显示在上述集合中
我写了一篇文章,其中包括一个代码示例,介绍了如何不考虑任何solutionfoldersvar Content=File.ReadAllText(SlnPath);
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]);
}
正则表达式projReg=新正则表达式(
“项目\(\”\{[\\w-]*\\\\\\“\\)=\”([\\w\]*.*),\“(.\\\.(cs | vcx | vb)项目)”
,RegexOptions.Compiled);
var matches=projReg.matches(Content.Cast();
var Projects=matches.Select(x=>x.Groups[2].Value.ToList();
对于(int i=0;i
编辑:根据Kumar Vaibhav的评论,修改了正则表达式以包含“*”这里有一个非常优雅的解决方案: John Leidegren的答案涉及到包装内部的
Microsoft.Build.Construction.SolutionParser
类。目前您可以在VS中使用以获取该信息。使用powershell获取项目
命令
Get-Project -All
如果需要在非Windows计算机上执行此操作,可以使用以下Bash命令:
grep”项目(“NameOfYourSolution.sln | cut-d''''-f4
自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
Add Type-Path(${env:ProgramFiles(x86)}+'\Reference Assemblies\Microsoft\MSBuild\v14.0\Microsoft.Build.dll')
$solutionFile=''
$solution=[Microsoft.Build.Construction.SolutionFile]$SolutionFile
($solution.ProjectsInOrder |其中对象{$\.ProjectType-eq'knowntobembuildformat'})。RelativePath
项目对象上还有很多其他属性(ProjectName、AbsolutePath、Configuration等)可能会用到。在上面的示例中,我使用ProjectType筛选解决方案文件夹。诀窍是选择正确的MsBuild.dll。 在VS2017下,它实际上是“C:\Program Files(x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\amd64\Microsoft.Build.dll” (不要在引用中使用标准Msbuild ddl。浏览到此路径) c#: 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}
}
}
我知道这可能已经回答了这个问题,但我想分享一下我读取sln文件的方法。在运行期间,我还要确定项目是否为测试项目
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"
}
希望这将是有帮助的。要通过以下方式扩展:
这将仅过滤到.csproj
文件,并根据文件
字段和包含sln
文件的路径添加每个文件的完整路径
使用获取项目解决方案MySolution.sln |选择对象全名
获取每个完整文件路径
我想要完整路径的原因是能够访问每个项目文件旁边的packages.config
文件,然后从所有文件中获取包:
Get-ProjectInSolution MySolution.sln |
%{Join-Path ($_.FullName | Split-Path) packages.config} |
%{select-xml "//package[@id]" $_ | %{$_.Node.GetAttribute("id")}} |
select -unique
上面的方法可以工作,但有一个小问题。如果你的项目命名为“AB.CD”-我的意思是当“.”在那里时,正则表达式就不会识别这些。下面的小改动会使它工作起来-正则表达式projReg=new正则表达式(“Project\(\”{[\\w-]*\\\\\\”=“([\\w\]*.\”,“(.\\\\\\”(cs\\\;vcx\\\\ vb)proj)\”,RegexOptions.Compiled)@Kiquenet我恐怕不明白您的评论没有任何用于读取sln文件的解析器C#类?类似于哪个Visual Studio
版本
?这只能在VS扩展中使用,因此对于任何想要在解决方案中读取源项目的独立工具的人来说都是无用的。您可以获得对的引用,也可以访问$d从package manager控制台执行te
。如果您根本没有运行VS,那么您需要一个替代解决方案。新的MSBuild包现在包含用于解析解决方案和项目文件的类,但这些仍然是预RTMupdated链接:我知道这很旧,但很漂亮。为我节省了大量时间。如果需要,您可以过滤掉sol通过在第2行和第3行之间添加一个额外的选择字符串来删除文件夹,如下所示:选择字符串“{2150E333-8FDC-42A3-9474-1A3956D46DE8}”-不匹配
对于VS2017,它位于VS2017的“C:\Program Files(x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\amd64\Microsoft.Build.dll”下
而且很烦人,但是对于sqlprojs文件,项目类型未知[SolutionProjectType]::未知