43

To keep our house in order, I want to automatically assemble licenses for project dependencies in our documentation, rather than having to add them manually.

Does anybody know a simple way to traverse programmatically a set of CSPROJ files and extract the license information for the referenced packages as a link or string?

2
  • When you say licence information you mean a short string representing the licence type or a link pointing to the licence page on the web? How would you like this information to be returned, in a console window or, for example, in a CSV/HTML file?
    – mguassa
    Jun 14, 2015 at 20:01
  • I could take either the link or a string. I'm more looking for a programmatic way to access the information in the first place
    – Byron Ross
    Jun 16, 2015 at 13:58

4 Answers 4

46

One way I know to get such information is by using PowerShell in the Package Manager Console, from within Visual Studio.

The Package Manager Console is a PowerShell console within Visual Studio used to interact with NuGet and automate Visual Studio.

Basically you can use the Get-Package cmdlet to get a list of packages referenced in a specific project (or in an entire Solution). Regarding the license information for each package, for what I've seen you can only get the license URL and not just a short string representing the license type.

Here's an example for a Solution of mine returning a list of entries, each one consisting of the package identifier and the link to the license:

Get-Package | Select-Object Id,LicenseUrl

The output is something like this:

get-package output

Other elements that can be returned are documented in the Nuspec reference, in the metadata section (e.g. the version of the package, a short description, etc.).

5
  • 3
    Just a note - In VS2015 'LicenseUrl' always returns an empty string. NuGet documentation says 'LicenseUrl' will be deprecated from v3.x on wards, buts does not mention about any alternatives Nov 20, 2015 at 5:32
  • As of 4/24 via VS2017 this answer works.
    – justSteve
    Apr 24, 2018 at 8:48
  • When I use Get-Package command by itself it doesn't output a LicenceUrl column. How can I find out if, other columns I want to list, exist like, licence type (mit/apache) or version?
    – Engin
    Jan 5, 2021 at 17:01
  • 1
    this doesnt seem to work now that licenceUrl is deprecated
    – Ewan
    Apr 22, 2021 at 9:59
  • Is there a solution for dotnet? Jul 23, 2021 at 17:37
10

Based on multiple sources, I've made a PowerShell script that reads all NuGet packages and fetches the license files and put that in a folder called "licenses". The script should be run on the root of the project (where the "packages" folder is located).

# Run in Package Manager Console with `./download-packages-license.ps1`.
# If access denied, execute `Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned`.

Split-Path -parent $dte.Solution.FileName | cd; New-Item -ItemType Directory -Force -Path ".\licenses";
@( Get-Project -All | ? { $_.ProjectName } | % {
    Get-Package -ProjectName $_.ProjectName | ? { $_.LicenseUrl }
} ) | Sort-Object Id -Unique | % {
    $pkg = $_;
    Try {
        if ($pkg.Id -notlike 'microsoft*' -and $pkg.LicenseUrl.StartsWith('http')) {
            Write-Host ("Download license for package " + $pkg.Id + " from " + $pkg.LicenseUrl);
            #Write-Host (ConvertTo-Json ($pkg));

            $licenseUrl = $pkg.LicenseUrl
            if ($licenseUrl.contains('github.com')) {
                $licenseUrl = $licenseUrl.replace("/blob/", "/raw/")
            }

            $extension = ".txt"
            if ($licenseUrl.EndsWith(".md")) {
                $extension = ".md"
            }

            (New-Object System.Net.WebClient).DownloadFile($licenseUrl, (Join-Path (pwd) 'licenses\') + $pkg.Id + $extension);
        }
    }
    Catch [system.exception] {
        Write-Host ("Could not download license for " + $pkg.Id)
    }
}

Disclaimer: I'm no PowerShell expert. Run at your own risk :)

I couldn't find any simple code that detects which license the NuGet package has, based on it's license file. The only project that comes close to a solution is Licensee, but this is build in Ruby.

3
  • The "packages" folder is not used for modern solutions using PackageReference. It seems your answer doesn't require this folder - you may want to write something like "where the sln file is located). Feb 6, 2020 at 7:43
  • 1
    Unfortunately, most license URLs now point to HTML-only versions (early 2020). For example, licenses.nuget.org ignores any "Accept: text/plain" (or json) headers and returns html regardless. Feb 6, 2020 at 8:03
  • @dominic-cerquetti Maybe you can post your changes in your own answer. They look useful.
    – jerone
    May 18, 2021 at 8:00
1

I managed to get the licence information using the following command:

@( @(Get-Project -All | ForEach-Object { Get-Package -ProjectName $_.ProjectName }) | Select Id -Unique ) | ForEach-Object { $pkg = $_ ;$pkgId = $_.Id ; if ($pkgId -notlike  'microsoft*'){ $url = Open-PackagePage $pkgId -License -WhatIf -PassThru; Write-Host "$pkgId $url"}}
1
  • 2
    Unfortunately this no longer works, as Open-PackagePage is now deprecated
    – sfuqua
    Apr 22, 2021 at 17:16
1

There is now a project called "Nuget License Utility" for .NET:

A .net core tool to print the licenses of a project. This tool support .NET Core and .NET Standard Projects.

Not the answer you're looking for? Browse other questions tagged or ask your own question.