Search code examples
msbuildnugetcsprojmsbuild-15packagereference

PackageReference Resolve Version Logic as API


Is there any accessible API via an MSBuild task, target or otherwise that allows me to query what version of a NuGet package a given PackageReference will resolve (or has already resolved) to?

For example, if I have a csproj with

<PackageReference Include=“MyPkg” Version=“1.*”/>

And I have a custom target where I want to

<MyTarget>
  <GetVersionOfResolvedPackageReference Name=“MyPkg” OutputProperty=“IWantToKnowThis” /> <!— or something —>
  ...

Solution

  • From How NuGet resolves package dependencies:

    When the NuGet restore process runs prior to a build, it resolves dependencies first in memory, then writes the resulting graph to a file called project.assets.json in the obj folder of a project using PackageReference. MSBuild then reads this file and translates it into a set of folders where potential references can be found, and then adds them to the project tree in memory.


    <#
    .Synopsis
        Represents the method that
        returns the project.assets
        content as object.
    #>
    function Get-ProjectAssest([System.String]$Assest) {
    
        return (Get-Content $Assest | ConvertTo-Json | ConvertFrom-Json).value |
                                                       ConvertFrom-Json
    }
    
    Get-ChildItem -Path . 'project.assets.json' -Recurse | ForEach-Object { Get-ProjectAssest($_.FullName) } | ForEach-Object {
    
        # K = Package Identity
        # V = Package Version
        $_.libraries | ForEach-Object { $_.PSObject.Properties.Name } | Out-File 'PackageReference.ini' -Append 
    }
    

    This PowerShell script recursively parses directories to find project.assets.json and writes result in PackageReference.ini file. You can call script from MSBuild via Exec task and after that read file via ReadLinesFromFile and performing further processing.


    NOTE: Represented script will be produce duplicates of PackageReference lines for multiple projects.