29

I'm looking for a way to get a list of all used NuGet packages in every project in a solution (and specifically the version) using command-line script and not manually in Visual Studio.

Using the Package Manager Console with the command "Get-Package" gives me what I want, but it is unavailable outside of VS.

I'm using is a local NuGet feed. My default package management format is PackageReference.

Any idea would be helpful

Josef Ginerman
  • 1,460
  • 13
  • 24
Avihay
  • 399
  • 1
  • 4
  • 8
  • 1
    Can't you just read them from the project files? – stuartd Nov 22 '18 at 17:32
  • they are explicitly listed in plain text packages.config for each project. There are usually hints as to the location of the package in the project files, but Nuget Package restore uses the packages.config. –  Nov 22 '18 at 18:01
  • 1
    @JeffDavies Thank for your answer. I have a solution with more than 150 projects. so search it may not be the best solution for me, but that will do the work. thanks! – Avihay Nov 25 '18 at 08:10
  • @Avihay, this powershell command will list all packages.configs: Get-ChildItem -Path $path -Recurse -Filter "packages.config" | select fullname . I'm not sufficiently versed in powershell to cat the contents of files from this list. Could easily do it in Bash. –  Nov 25 '18 at 14:22

7 Answers7

27

PackageReference as a package management format only works on a per project basis. So you would need to "analyze" each project individually.

Update:

In .NET SDK versions, 2.2.100 and newer, dotnet list package.

Old version:

From the commandline, there "will" be a way to list all the packages. It's the "dotnet list package" command. I say will, because it's still in preview. You can download the 2.2.100 version from here. Related spec.

The simplest usage example is:

dotnet list YourSln.sln package

If you do not want to use a dotnet.exe preview, you can consider writing your own tool, by reading the assets files for each project, which is what the actual command does. For reference, see code here and here

imps
  • 1,423
  • 16
  • 22
  • 1
    This only applies to .NET Core and .NET 5.0. – Ed Greaves May 11 '21 at 13:37
  • 2
    It works with SDK based projects. There is a difference between target framework and the tooling. This is a tooling feature, so not really related to .NET 5.0. It works with SDK based projects, which can target much more than just .NET Core. – imps May 11 '21 at 20:36
18

Run this command Get-Package | Select-Object Id, Version, LicenseUrl, ProjectName in package manager console in Visual Studio. taken from this answer: https://softwareengineering.stackexchange.com/a/286981

stambikk
  • 1,175
  • 12
  • 23
11

I'm sure there are better ways to do this, but here's a round-the-houses PowerShell way when using PackageReferences:

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

Run it in the folder where the .sln lives.

It produces output like this:

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

I intentionally remove duplicates; you could omit that part if you prefer.

In my case, this matches the output from Get-Package with the one exception being Microsoft.NETCore.App, as that is not listed as a dependency anywhere, but is probably rather derived from <TargetFramework>netcoreapp2.1</TargetFramework>.

sellotape
  • 8,034
  • 2
  • 26
  • 30
  • Nice idea. but for some reason it does not show the version number. i.e `` Is there something that i missing? @sellotape – Avihay Nov 25 '18 at 08:38
  • @Avihay - it's just showing the line in the .csproj there. Have a look inside your .csproj's and see whether there is something fundamentally different to those in my example. – sellotape Nov 25 '18 at 08:45
  • Admittedly a nice attempt, but anyone reading this must remember that this may not accurately represent the package references as MSBuild or dotnet cli would resolve them. More complex scenarios implying conditional version referencing would likely cause issues. There might also be a reference to a package that is set once for all projects, in a `Directory.Build.props` file. Granted, this is very unlikely. But it might happen in some shops having private packages that are merely tools for MSBuild assistance and/or only containing private assets. – Crono Aug 27 '20 at 21:38
  • Just an idea: perhaps extracting the output of `dotnet list package` might be "safer"? – Crono Aug 27 '20 at 21:41
5

Since packages dependencies have been moved into the package.config file, here is an updated version of the Powershell provided by https://stackoverflow.com/users/2385218/sellotape

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

Output be will be like this:

<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" />
Benjamin Soulier
  • 2,223
  • 1
  • 18
  • 30
4

For .NET Core 2.2 and later projects where PowerShell is available, try

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

and

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

in POSIX-like environments.

MrBink
  • 740
  • 5
  • 17
2

Writing a script that finds the occurrences of the tag PackageReference on each one of the csproj files is a great idea, as proposed by selotape.

This solution won't work if your csproj file has something like this:

<PackageReference Include"SomePackage">
    <Version>1.0.42</Version>
</PackageReference>

Even though I recommend that you change the format to state the version in-line (as in the .NET Standard csproj format), maybe you don't have time to do it for all your projects.

Solution:

Using a C# script, you could get all the items in your csproj files containing PackageReference as their tag-name. Then you could do one of two things:

  1. Continue text scrapping until you find (for each item) a regex like this: (Version="*"), which will allow you to find the version for each PackageReference
  2. Serialize the items to your favorite format (JSON works) to get the data divided in a dictionary, where you can just get the name and version from, together with any other data you might need.

I hope this helps.

Josef Ginerman
  • 1,460
  • 13
  • 24
0

I wrote a C# script for this purpose, but it doesn't directly use the SLN file. It searches instead within a given directory for any packages.config file. Duplicates will be visible within the column 'assemblies' (list of all assemblies that use the specified package). The output will be a CSV file to any given location.

You can just copy / download or adjust the code from here: Source Code

You could also compile the above written source code using CMD / Powershell: Compiling/Executing a C# Source File in Command Prompt