问题标签 [assembly-loading]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
54 浏览

c# - 在运行时使用本机依赖项(和其他文件/文件夹)加载程序集

我想在运行时加载程序集 A。这个程序集 A存在于应用程序的子文件夹中,并且对一些其他本机程序集、一些 jar 文件和 jre 文件夹具有运行时依赖项(所以我们正在谈论一些 java 包装器)。所有这些依赖项都存在于与Assembly A相同的文件夹中。
该图将是这样的:
在此处输入图像描述

问题是:
由于应用程序(消费者)构建文件夹中不存在Assembly A运行时依赖项,因此出现异常并且无法使用它。

这是在运行时加载程序集的源代码示例以及该程序集拥有的类型实例的使用。当我调用_ = instance.GetSomething(). 例外是:

System.TypeInitializationException:“'AssemblyA_Dependency.Type' 的类型初始化程序引发了异常。”

PS:请记住,如果我将所有Assembly A依赖项复制到使用者构建文件夹中,它将正常工作。

有没有办法克服这个问题?

0 投票
1 回答
380 浏览

.net - AssemblyLoadContext 和 Assembly.LoadFrom(path)

GetCustomAttribute 在自定义 AssemblyLoadContext 中找不到通过“Assembly.LoadFrom(path)”加载的程序集的属性。

负载流:

  • 主应用程序具有自定义 AssemblyLoadContext
  • 自定义 AssemblyLoadContext 指向程序集 X 并加载它
  • 自定义 AssemblyLoadContext 执行 EnterContextualReflection
  • 自定义 AssemblyLoadContext 从程序集 X 创建类型的实例
  • 该类型执行 Assembly.LoadFrom(path) 并成功加载程序集 Y

程序集 Y 上有一个程序集级属性。该属性来自静态链接到 X 和 Y 的共享程序集 (TechTalk.SpecFlow)。

当我尝试通过它的类型版本获取属性时,Attribute.GetCustomAttribute它返回 null。

当我通过属性列出所有属性时,CustomAttributes该属性就在那里并且它具有完全相同的程序集全名。

如果我尝试将其转换为静态已知类型,则会出现奇怪的异常:

[A]TechTalk.SpecFlow.Plugins.RuntimePluginAttribute 不能转换为 [B]TechTalk.SpecFlow.Plugins.RuntimePluginAttribute。类型 A 源自 'TechTalk.SpecFlow, Version=3.1.0.0, Culture=neutral, PublicKeyToken=0778194805d6db41' 在位置 'c:\Users\yapaxi\source\repos\IntegrationTests\IntegrationTests.ChargingTokens\bin 的上下文'Default'中\Debug\netcoreapp3.1\TechTalk.SpecFlow.dll'。类型 B 源自 'TechTalk.SpecFlow, Version=3.1.0.0, Culture=neutral, PublicKeyToken=0778194805d6db41' 在位置'c:\Users\yapaxi\source\repos\IntegrationTests\IntegrationTests.ChargingTokens\bin 的上下文'Default'中\Debug\netcoreapp3.1\TechTalk.SpecFlow.dll'。

出于某种原因,它认为两个程序集都加载到了Default上下文中,这很奇怪,因为所有加载都发生在自定义程序集加载上下文中。

如果我在它显示自定义加载上下文的名称AssemblyLoadContext.CurrentContextualReflectionContext.Name之前尝试- 正如预期的那样。Assembly.LoadFrom

为什么它仍然认为程序集已加载到默认上下文?主应用程序甚至没有对这些程序集的静态引用——它根本没有任何自定义引用。

如果我直接运行程序集 X(没有 AssemblyLoadContext)它一切正常。

环境:

  • 网核3.1
  • SDK 3.1.201
  • VS 16.4.3
0 投票
2 回答
1987 浏览

c# - 如何在 .NET Core 中卸载程序集/使其可收藏?

如何在 .NET Core 中卸载程序集?

注意:
.NET Core 不支持 AppDomain。

背景:
我必须动态评估用户生成的 VisualBasic 表达式。
为此,我使用 Roslyn 动态编译表达式。
我从 Roslyn 编译器生成的字节数组中加载生成的程序集。
然后我创建一个实现抽象类的实例(所以我不必使用反射)。然后我调用抽象类的方法EvaluateExpression。
完成后,我想卸载加载的程序集(否则我会有内存泄漏的乐趣)。
所以我在评估表达式后立即卸载程序集:

(loadContext在生成时保存在抽象类中)

到目前为止一切正常,但是在x.LoadContext.Unload();,我得到了

System.InvalidOperationException:“无法卸载不可收集的 AssemblyLoadContext。”

有可能解决这个问题吗?
我怎样才能使组装成为收藏品?
另外,我注意到我可以加载具有相同类名的程序集(如您所见,代码中没有命名空间)
这在多线程环境(又名网络)中的表现如何?
我可以无限地加载和加载动态生成的类的不同版本,直到机器用完 RAM 而没有故障吗?
或者为什么在两次加载同一个类时这会起作用?

抽象类:

0 投票
1 回答
206 浏览

.net - 绑定重定向在 VSPackage/VSIX 中无效

主要问题

我正在使用 VS2017 (15.9.25) 开发 VSIX VSPackage。

该包使用MySqlConnector 1.0.0NuGet 包,而 NuGet 包又依赖于System.Memory 4.5.4包含System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51程序集的 NuGet 包。

当我使用 Visual Studio 实验实例在调试模式下运行我的 VSPackage 时,我的插件会加载,我可以看到我的自定义选项页面和我添加到 VS 上下文菜单的自定义命令。但是当我实际运行自定义命令(尝试使用 检索一些数据MySqlConnector)时,数据库连接失败,因为System.Memory程序集无法加载。

FileNotFoundException 详细信息

异常消息中提供了一些我不完全理解的调试信息:

附加装配加载细节

Myapp.config包含以下绑定重定向:

bin/Debug文件夹和生成的.vsix文件都包含MySqlConnector.dll 1.0.0System.Memory.dll 4.0.1.1

查看MySqlConnector.dll使用 ReSharper 的程序集资源管理器,我看到它引用System.Memory 4.0.1.0了,这是无法加载的程序集。

我的问题是:

  1. 为什么FileNotFoundException提到4.0.1.0?绑定重定向不应该导致 .NET 尝试加载肯定存在的 4.0.1.1 吗?
  2. 在 VSIX/VSPackage 上下文中配置绑定重定向需要做些什么特别的事情吗?
  3. 额外的程序集绑定/加载诊断(例如=== Pre-bind state information ===等)实际上意味着什么?
  4. 我需要更改哪些内容才能正确加载此程序集?

更多细节

我从面向 .NET 4.6 的标准 VS2017 VSIX 包项目模板开始,后来将我的项目重新定位到 .NET Framework 4.7.2。

我认为该问题可能是由 .NET Fx 4.7.2 中包含的类型引起的,但在针对 .NET Fx 4.6 时是单独提供的,因此我尝试在将目标更改为 4.7.2 后重新安装 theMySqlConnectorSystem.MemoryNuGet 包。它没有任何区别。

我正在使用传统packages.config风格的 NuGet 配置。

VSIX 包使用 NuGet 包MySqlConnector 1.0.0项目主页)。该包没有明确列出 .NET 4.7.2 的任何依赖项:

NuGet 包管理器中的 MySqlConnector 依赖项列表

但似乎依赖项.NETFramework,Version=4.7.1也适用于4.7.2,因为安装MySqlConnector会导致System.Memory 4.5.4NuGet 包也被安装。这会将System.Memory 4.0.1.1程序集的引用添加到我的 VSIX VSPackage 项目中,其中包含Copy Local == True

System.Memory 引用属性

选中项目属性中“自动生成绑定重定向”的复选框: 检查自动生成绑定重定向

但是,奇怪的是,文件中没有<AutoGenerateBindingRedirects>元素。csproj也许该元素由于某种原因不适用于 VSIX 项目,或者它在某些时候变成了隐式行为?

当我构建我的项目时,该System.Memory.dll文件正在从 NuGet 包文件夹复制到二进制输出文件夹中,正如我所期望的:

Windows 资源管理器屏幕截图在输出文件夹中显示 System.Memory.dll

使用 ILSpy 检查二进制输出文件夹中的文件证明它是最新版本,并且与以下中的程序集绑定重定向匹配app.config

使用 7-zip打开.vsix输出文件夹中的文件显示 VSIX 还包含System.Memory.dll

VSIX 存档内容

0 投票
1 回答
277 浏览

c# - 如何在不编译 .NET Core 的情况下加载程序集并调用它们的方法

我有一个 .NET Core 项目,它需要接收一个字符串,该字符串确定要使用的身份验证逻辑,然后使用它。

身份验证逻辑需要是位于目录中并实现接口的 DLL。我们应该可以选择向目录添加更多实现接口的 DLL,而无需编译项目。

.NET Framework 有一个完美的解决方案 - MEF(托管扩展框架)。不幸的是,.NET Core 仅部分支持 MEF(不支持DirectoryCatalog,允许扫描目录和加载程序集)

在 .NET Core 中是否有类似/更好的方法来实现这一点?

0 投票
0 回答
226 浏览

wpf - AssemblyLoadContext.Unload 不卸载 Wpf 库

我在这里写的是在 Github 上发布的同一个问题,因为我最近在那里没有看到太多的流量。

  • .NET Core 版本:3.1.9 和 .Net 5
  • Windows 版本:10.0.18363
  • 该错误是否也在 .NET Framework 4.8 的 WPF 中重现?:不支持 AssemblyLoadContext

我正在尝试按需加载和卸载 Wpf App 库(以及所有相关的依赖项)。一切正常,但在调用 Unload 方法时没有任何程序集被卸载。如果我用包含一些示例方法的 .Net Core 库替换 Wpf 库,我可以看到在几次 GC 迭代后从 VS Modules 窗口中删除了该库。

如果我没记错的话,我应该期望 AssemblyLoadContext 加载 WpfLibrary 和相关依赖项(PresentationCore、PresentationFramework 等),但 WpfLibrary 是唯一加载的。所有其他依赖项似乎都加载到默认上下文中。可能是我误解了它是如何工作的,但在我看来,框架依赖项阻止了卸载。

此外,我不确定我报告的问题是否与this和/或this相关。

我附上了一个结构如下的示例项目:

项目 1(MainApp,一个添加了 System.Windows.Forms 引用以启用消息泵的控制台项目)

项目 2(代理接口)

项目 3(在项目 2 中实现接口的常规 wpf 库)

UnloadWpfLibrary.zip (“MainApp”文件夹内的解决方案文件)

进一步更新: DotNet 团队将该问题添加到“未来里程碑”中,因此我必须推断他们认为这是一个错误。我不知道我们什么时候会看到 Wpf 与 AssemblyLoadContext 一起工作。似乎有一种解决方法涉及将目标程序集拆分为两个单独的程序集。我附加了带有建议修改的项目,这次卸载了两个程序集之一,但所有其他程序集仍被加载,包括 WpfLibrary。

UnloadWpfLibraryWithWorkaround.zip

我认为对我来说是时候放弃并重新使用 IPC(命名管道)了,尽管我不确定这是否可以成为有效的替代品。可能是我遗漏了一些东西,而更专业的人可以做进一步的进展,并在此处附上正确修改的项目,这对所有想要使用 ALC 加载和卸载 WPF 的用户都有很大的好处。仅按需加载和卸载 wpf 程序集将总共有 4 个项目,这并不完全干净,但如果最终结果相同,那将是可以接受的。

0 投票
1 回答
352 浏览

c# - Spire PDF SaveToFile 崩溃程序

我正在尝试将 PDF 文件保存到文件夹,为此我正在使用 Spire.PDF。

我正在从 byte[] 创建 PdfCodument,当我尝试将其保存到文件时,我收到一条错误消息并且程序失败。

错误消息说:

无法加载文件或程序集“Spire.License,Version=1.3.8.40,Culture=natural...”或其依赖项之一。该系统找不到指定的文件。

问题是我参考了 Spire.License dll,它来自版本 1.3.8.40。

我究竟做错了什么?

先感谢您!

0 投票
1 回答
43 浏览

c# - `GetReferencedAssemblies` 是 `AppDomain.CurrentDomain.GetAssemblies()` 的子集吗?

我想测试一些我写的反射代码。

如果 ReferencedAssemblies 尚未加载到 AppDomain 中,则会发生边缘情况,即如果返回以下表达式true

我有两个问题:

  1. 那还能回来true吗?(我认为“是”[因此标题问题的答案是“否”],尽管我不确定)。
  2. 假设它可以......那么为了单元测试的目的,我该如何安排呢?
0 投票
1 回答
43 浏览

c# - .NET Core 中的并行程序集

我正在开发项目对 1.0 版 PROJECTB 具有 nuget 依赖关系的应用程序。但是在开发场景中,我想使用这个 PROJECTB 作为子模块。将该项目添加到解决方案并将版本更改为 2.0

但是只有 1.0 版的 PROJECTB 在 bin 文件夹中。我尝试手动将 2.0 版的 PROJECTB 添加到我的主项目的项目引用中,但出现错误:

已导入具有相同简单名称 PROJECT2 的程序集

0 投票
1 回答
102 浏览

c# - AssemblyLoadContext 加载和卸载在不同的函数中得到不同的结果

这是来自微软文档的代码。请注意代码中的注释

这是插件接口代码

这是加载和卸载方法(我从microsoft doc修改了代码)

这是 wpf 程序代码的一部分

如果卸货码和装货码不在一起

但是,如果在 Wpf 初始化函数“MainWindow()”或 wpf 应用程序事件(例如 Loaded 事件、ContentRendered 事件、Activated 事件)中没有调用加载代码,它将起作用。

谁能告诉我为什么?这可能是一个错误吗?

您可以将代码复制到新的 wpf 程序中进行测试。我的运行时框架是.Net 5