30

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?

  • 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 '15 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 '15 at 13:58
29

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.).

| improve this answer | |
  • 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 – James Poulose Nov 20 '15 at 5:32
  • As of 4/24 via VS2017 this answer works. – justSteve Apr 24 '18 at 8:48
8

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.

| improve this answer | |
  • 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). – Patrick Stalph Feb 6 at 7:43
  • 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. – Patrick Stalph Feb 6 at 8:03
0

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"}}
| improve this answer | |

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