【问题标题】:Extract a dll from a nuget package using nuget.client使用 nuget.client 从 nuget 包中提取 dll
【发布时间】:2020-04-12 09:34:25
【问题描述】:

我正在尝试以编程方式从 nuget 包中提取 dll 并在运行时加载 dll。

我想避免使用任何命令行工具 - 我希望我的程序完全独立,而不是依赖外部可执行文件。

我正在尝试使用https://www.nuget.org/profiles/nuget 中列出的各种 nuget.client nuget 包,但没有任何文档,我不知道如何使用。

我有 nupkg,我可以通过 PackageReader 计算出 nupkg 中 dll 的位置,但我不知道如何提取 nupkg 以便将文件取出。

编辑

感谢那些指出 nupkg 只是一个 zip 的人。我现在做了以下事情:

            var archive = new ZipArchive(downloadResourceResult.PackageStream);

            var entry = archive.GetEntry(dllPath);

            var assemblyLoadContext = new System.Runtime.Loader.AssemblyLoadContext(null, isCollectible: true);
            var assembly = assemblyLoadContext.LoadFromStream(entry.Open());

但是这会引发 NotSupportedException 并带有以下堆栈跟踪

System.IO.Compression.DeflateStream.get_Length()   at System.Runtime.Loader.AssemblyLoadContext.LoadFromStream(Stream assembly, Stream assemblySymbols)   at System.Runtime.Loader.AssemblyLoadContext.LoadFromStream(Stream assembly)

【问题讨论】:

  • 提示:它是一个 zip 文件
  • nupkg 文件只是 zip 文件。只需像往常一样解压缩,然后查看相应的子文件夹...
  • 好的,我已经做到了。现在,当我尝试从 zip 文件流中加载它时,我从 System.IO.Compression.DeflateStream.get_Length() 得到一个 NotSupportedException

标签: c# nuget


【解决方案1】:

这是下载 nuget 包并加载它的完整方法。它只是一个 POC - 您需要针对您的用例进行配置。

        public async Task<Assembly> LoadFromNuget(string id, string version, string? nugetFeedUrl = null, CancellationToken cancellationToken = default)
        {
            var repository = Repository.Factory.GetCoreV3(nugetFeedUrl ?? "https://api.nuget.org/v3/index.json");
            var downloadResource = await repository.GetResourceAsync<DownloadResource>();
            if (!NuGetVersion.TryParse(version, out var nuGetVersion))
            {
                throw new Exception($"invalid version {version} for nuget package {id}");
            }
            using var downloadResourceResult = await downloadResource.GetDownloadResourceResultAsync(
                new PackageIdentity(id, nuGetVersion),
                new PackageDownloadContext(new SourceCacheContext()),
                globalPackagesFolder: Path.GetTempDirectory(),
                logger: _nugetLogger,
                token: cancellationToken);

            if (downloadResourceResult.Status != DownloadResourceResultStatus.Available)
            {
                throw new Exception($"Download of NuGet package failed. DownloadResult Status: {downloadResourceResult.Status}");
            }

            var reader = downloadResourceResult.PackageReader;

            var archive = new ZipArchive(downloadResourceResult.PackageStream);

            var lib = reader.GetLibItems().First()?.Items.First();

            var entry = archive.GetEntry(lib);

            using var decompressed = new MemoryStream();
            entry.Open().CopyTo(decompressed);

            var assemblyLoadContext = new System.Runtime.Loader.AssemblyLoadContext(null, isCollectible: true);
            decompressed.Position = 0;
            return assemblyLoadContext.LoadFromStream(decompressed);
        }

您必须实施或使用 Nuget ILogger 的某个版本才能下载 nupkg。

【讨论】:

    【解决方案2】:
    1. 您可以将 nuget 扩展名重命名为 zip 扩展名,并且应该能够解压缩到文件夹。
    2. 现在,您可以从解压缩的文件夹中获取 dll。

    【讨论】:

      猜你喜欢
      • 2017-02-27
      • 2017-09-02
      • 2013-01-14
      • 1970-01-01
      • 2014-12-04
      • 2016-04-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多