Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
243 views
in Technique[技术] by (71.8m points)

c# - How can I list all local packages in the NuGet v3 API

For context, I'm building an application that needs to download/unpack packages and their dependencies from arbitrary package sources (including the public gallery by default) and upgrade those packages to the latest version when requested. There are no project.json files or similar, it's all code driven. It's not a particularly complicated use case and didn't require too much code in the v2 APIs.

In v3 however, I can't figure out how to correctly interact with the local package store. For example, the FolderNuGetProject class that I would have thought lists all the packages on disk at a given location in FolderNuGetProject.GetInstalledPackagesAsync() just returns an empty enumerable. To make matters more confusing, FolderNuGetProject.PackageExists() actually does return whether the package exists on disk, which means GetInstalledPackagesAsync() and PackageExists() appear to be inconsistent.

None of the other NuGetProject derivatives appear related to the file system. Is there some other way of listing the packages that have been installed into a particular folder? If I need to create my own NuGetProject (and I'm hoping I don't), are there any methods that will help with parsing NuGet-generated folder names into package IDs and versions, or is the only reliable way of getting the ID and version to open the nuspec (and are there any easy to find methods for that)?

One interpretation of why this isn't working as I expect is that NuGetProject.GetInstalledPackagesAsync() isn't actually intended to get the installed packages (I.e., those that have been downloaded and unpacked), but rather those that have been declared in whatever project system is in use. For example, the BuildIntegratedNuGetProject class appears to return package references for the packages in the project.json, regardless of their status on disk. That would also explain why FolderNuGetProject just returns an empty enumerable, because there are no "declared" packages if you're just looking at the local repository.

TL;DR: What is the best way to crawl the local package store and get the packages and versions that are present there?

(this was also issue #2664 on the NuGet GitHub project, but was moved here by request)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Introduction

I have the same question and I looked your post on GitHub, Google and here. I try a lot of things to find the local packages. I found some solutions, but I don't know if it's the best way to do it. I posted a question about local packages too, because I can list all local packages, but I can't have the AssemblyReferences property (dll).

Code example

var rootPath = @"pathWhereNuGetPackagesAre";
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...

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

// The trick here is to put the local nuget path, not using the URL : https://api.nuget.org/v3/index.json
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

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);
    }
}

Hope this will help!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...