获取解决方案中使用的所有NuGet包列表

30

我正在寻找一种使用命令行脚本获取解决方案中每个项目中所有已使用 NuGet 包列表(特别是其版本)的方法,而不是在 Visual Studio 中手动操作。

使用“包管理器控制台”命令 "Get-Package" 可以得到我想要的结果,但在 VS 外部不可用。

我正在使用本地 NuGet feed。 我的默认包管理格式是 PackageReference。

任何想法都将有所帮助。


1
你不能直接从项目文件中读取它们吗? - stuartd
它们在每个项目的明文packages.config中被明确列出。通常在项目文件中会有关于包位置的提示,但Nuget Package恢复使用packages.config。 - user5292841
1
@JeffDavies 谢谢你的回答。我有一个超过150个项目的解决方案。所以搜索可能不是最好的解决方案,但那会起作用。谢谢! - Avihay
@Avihay,这个PowerShell命令将列出所有的packages.configs:Get-ChildItem -Path $path -Recurse -Filter "packages.config" | select fullname。我对PowerShell不够熟悉,无法从此列表中读取文件内容。在Bash中可以轻松完成此操作。 - user5292841
7个回答

29

PackageReference作为一个包管理格式,仅适用于每个项目的基础上。 因此,您需要单独“分析”每个项目。

更新:

在.NET SDK版本2.2.100及更高版本中,dotnet list package

旧版本:

从命令行,将有一种方法列出所有包。 这是“dotnet list package”命令。 我说将会,因为它还在预览中。 您可以从这里下载2.2.100版本。 相关规范

最简单的使用示例:

dotnet list YourSln.sln package

如果您不想使用dotnet.exe预览版,可以考虑编写自己的工具,通过读取每个项目的资产文件来实现,这就是实际命令所做的事情。

有关代码,请参见此处此处


1
这仅适用于.NET Core和.NET 5.0。 - Ed Greaves
2
它适用于基于SDK的项目。目标框架和工具有所不同。 这是一个工具功能,因此与.NET 5.0没有真正关系。它适用于基于SDK的项目,可以针对比.NET Core更多的内容。 - imps

18

谢谢,这对我来说是解决方案,但可能并不适用于所有人。+1给你 - Christian Müller

11

我相信有更好的方法来做这件事情,但是在使用PackageReferences时,以下是一种绕弯路的PowerShell方式:

Get-Content .\<solution>.sln | where { $_ -match "Project.+, ""(.+)""," } | foreach { $matches[1] } | % {Get-Content $_ | Find "<PackageReference Include" } | Sort-Object -Unique

将其运行在包含 .sln 文件的文件夹中

它会产生以下输出:

<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.5.0" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.1.2" PrivateAssets="All" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.4" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Http" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Options" Version="2.1.1" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.1.5" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2">
我会有意地删除重复项;如果您愿意,可以省略此部分。
在我的情况下,这与Get-Package的输出匹配,唯一的例外是Microsoft.NETCore.App,因为它不在任何地方列为依赖项,但可能是从<TargetFramework>netcoreapp2.1</TargetFramework>派生而来。

不错的想法。但出于某些原因,它没有显示版本号。 即 <PackageReference Include="Newtonsoft.Json"> 我是不是漏掉了什么? @sellotape - Avihay
@Avihay - 这只是在 .csproj 中显示该行。查看您的 .csproj 是否与我的示例有根本不同的地方。 - sellotape
可以承认,这是一个不错的尝试,但任何阅读此内容的人都必须记住,这可能无法准确地表示MSBuild或dotnet cli解析的软件包引用。更复杂的情况涉及条件版本引用可能会导致问题。还可能存在对在Directory.Build.props文件中为所有项目设置一次的软件包的引用。当然,这种情况非常不太可能发生。 但在某些商店中,可能会出现仅包含MSBuild辅助工具和/或仅包含私有资源的私有软件包。 - Crono
只是一个想法:也许提取 dotnet list package 的输出可能会更“安全”? - Crono

5

自从软件包依赖项已转移到 package.config 文件中,下面是由 https://stackoverflow.com/users/2385218/sellotape 提供的 Powershell 的更新版本。

Get-Content .\NP.sln | where { $_ -match "Project.+, ""(.+)\\([^\\]+).csproj"", " } | foreach { "$($matches[1])\packages.config" } | % { Get-Content $_ | Find "<package id" } | Sort-Object -Unique

输出结果将会是这样的:
<package id="AutoMapper" version="8.1.1" targetFramework="net47" />
<package id="BouncyCastle" version="1.8.5" targetFramework="net47" />
<package id="CsvHelper" version="12.1.2" targetFramework="net47" />
<package id="DnsClient" version="1.2.0" targetFramework="net47" />
<package id="EntityFramework" version="6.2.0" targetFramework="net462" />
<package id="EntityFramework" version="6.2.0" targetFramework="net47" />

4

对于使用.NET Core 2.2及以上版本且具备PowerShell的项目,请尝试以下操作:

(dotnet list package) -match '^.*>' -replace '^ +> ','' | % { $_.split(" ")[0] } | Sort-Object -Unique

并且

dotnet list package | grep '>' | sed 's/^ *> //g;s/ \+/ /g' | cut -f 1 -d ' ' | sort -u

在类POSIX环境下。

3
我们如何获得版本号? - Vivekh

2
编写一个脚本来查找每个csproj文件上PackageReference标签的出现次数是一个好主意,正如selotape所建议的那样。
如果你的csproj文件有类似下面的内容,这种解决方案就不起作用了:
<PackageReference Include"SomePackage">
    <Version>1.0.42</Version>
</PackageReference>

尽管我建议您更改格式以内联方式指定版本(如.NET Standard csproj格式),但也许您没有时间为所有项目执行此操作。
解决方案:
使用C#脚本,您可以获取所有csproj文件中包含PackageReference作为标记名称的项目。然后,您可以执行以下两个操作之一:
1. 继续文本抓取,直到找到每个项目的正则表达式,例如:(Version="*"),这将允许您找到每个PackageReference的版本。
2. 将项目序列化为您喜欢的格式(JSON有效),以便在字典中分隔数据,从中获取名称和版本以及其他所需数据。
希望这可以帮助您。

0

我为此编写了一个C#脚本,但它不直接使用SLN文件。相反,它在给定目录中搜索任何packages.config文件。 重复项将在“assemblies”列中可见(指定包使用的所有程序集列表)。 输出将是一个CSV文件,可以放置在任何给定位置。

您可以从这里复制/下载或调整代码: 源代码

您还可以使用CMD / Powershell编译上述编写的源代码: 在命令提示符中编译/执行C#源文件


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接