我正在尝试以编程方式从 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());
Run Code Online (Sandbox Code Playgroud)
但是,这会引发 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)
Run Code Online (Sandbox Code Playgroud)
这是下载 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);
}
Run Code Online (Sandbox Code Playgroud)
您必须实现或使用 Nuget ILogger 版本才能下载 nupkg。
| 归档时间: |
|
| 查看次数: |
5542 次 |
| 最近记录: |