How can I have assemblies (dll) for local packages

2019-07-21 15:12发布

问题:

Introduction

Hello everyone, I found a way to find the local NuGet packages using the NuGet v3 API. I don't know if I do it the correct way, but it works... There isn't a lot of documentation. The only interesting documentation I found is this blog. So, I don't know if I do it the correct way. I try to find some issues about my problem on the official NuGet GitHub. I didn't find anything interesting even on Google.

So, I kept my code and I tried to find a way to get the assemblies (dlls) when I search local packages with NuGet v3 API. I try a lot of NuGet classes, but nothing seems to return what I expected. Some functions return the package information, but the AssemblyReferences property is missing.

I know in the NuGet v2 API, the search functions return a IPackage. Now, in the v3, it is returning a IPackageSearchMetadata or a LocalPackageInfo depending on what functions you are calling. So, they changed the returned object.

So, is there a way to get the AssemblyReferences like the IPackage in the Nuget V2 API?

I don't know if it's an issue but, I posted on it on GitHub.

Code example using the Nuget V2 API (working)

var rootPath = @"pathWhereNugetPackageAre";
LocalPackageRepository repo1 = new LocalPackageRepository(rootPath);
var newtonsoft = repo1.FindPackagesById("Newtonsoft.Json").First();
//return the package and the assembly property because it's v2

Code example using the Nuget V3 API (what I tried)

var rootPath = @"pathWhereNugetPackageAre";
var logger = new Logger();

List<Lazy<INuGetResourceProvider>> providers = new List<Lazy<INuGetResourceProvider>>();
providers.AddRange(Repository.Provider.GetCoreV3());

FindLocalPackagesResourceV2 findLocalPackagev2 = new FindLocalPackagesResourceV2(rootPath);
var packageFound = findLocalPackagev2.GetPackages(logger, CancellationToken.None)
    .FirstOrDefault();
//found, but missing a lot of informations...

FindLocalPackagesResourceV3 findLocalPackagev3 = new FindLocalPackagesResourceV3(rootPath);
var packageNotFound = findLocalPackagev3.GetPackages(logger, CancellationToken.None)
    .FirstOrDefault();
// I don't know why it is null. It should be found

NuGetv3LocalRepository nugetV3LocalRepo = new NuGetv3LocalRepository(rootPath);
var newtonsoftToFound = nugetV3LocalRepo.FindPackagesById("Newtonsoft.Json")
    .FirstOrDefault();
// return empty I don't know why...

var supportedFramework = new[] { ".NETFramework,Version=v4.6" };
var searchFilter = new SearchFilter(true)
{
    SupportedFrameworks = supportedFramework,
    IncludeDelisted = false
};

PackageSource localSource = new PackageSource(rootPath);
SourceRepository localRepository = new SourceRepository(localSource, providers);
PackageSearchResource searchLocalResource = await localRepository
    .GetResourceAsync<PackageSearchResource>();

var packageFound3 = await searchLocalResource
    .SearchAsync("Newtonsoft.Json", searchFilter, 0, 10, logger, CancellationToken.None);
var thePackage = packageFound3.FirstOrDefault();
// found but missing the assemblies property

// Logger class
public class Logger : ILogger
{
    private List<string> logs = new List<string>();

    public void LogDebug(string data)
    {
        logs.Add(data);
    }

    public void LogVerbose(string data)
    {
        logs.Add(data);
    }

    public void LogInformation(string data)
    {
        logs.Add(data);
    }

    public void LogMinimal(string data)
    {
        logs.Add(data);
    }

    public void LogWarning(string data)
    {
        logs.Add(data);
    }

    public void LogError(string data)
    {
        logs.Add(data);
    }

    public void LogInformationSummary(string data)
    {
        logs.Add(data);
    }

    public void LogErrorSummary(string data)
    {
        logs.Add(data);
    }
}

I know I can list all dlls file using the DirectoryInfo, but I'm searching a NuGet class that does the logic.

回答1:

@emgarten He answered my question on GitHub

For finding packages in local folders take a look at: https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Core/NuGet.Protocol/Utility/LocalFolderUtility.cs

Note that v2 and v3 folders expect different structures and files to be present, so if a package is not returned it is likely because it isn't in the expected location or additional files beyond the nupkg were not in place.

You can read a package using PackageArchiveReader which gives you data similar to IPackage.

You can use the PackageArchiveReader for extracting informations on a NuGet package. You can use GetFiles(), or others functions (many functions are available). In my case, I used GetReferenceItems(), because it's grouped by target frameworks. So it's more interesting for getting the right assemblies with a target framework.

Note : If you having troubles finding packages with GetPackageV2() and GetPackageV3(), be sure that you have a valid V2 structure folder or V3 structure folder. I compared my NuGet folder with my NuGet Visual Studio folder and some files were missing (*.nuspec, *nupkg.sha512...). It should be this missing that the V3 search didn't work. I compared my NuGet folder with my last project (NuGet v2) and folders and files were the same. So, I used the GetPackageV2().

Hope this will help!