问题标签 [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 投票
1 回答
760 浏览

c# - MyAppDomain AssemblyResolve C#

我有一个 DLL,我在需要自己处理外部程序集负载的环境中使用它。我想将程序集加载到 AppDomain 中。当我使用 CurrentAppDomain 尝试此操作时效果很好,但是在我自己创建的应用程序域中执行此操作时失败。背景是我想在最后卸载appdomain,以便最终“释放”程序集。

我的问题是如何使用我创建的 appdomain 来加载程序集?

0 投票
1 回答
11626 浏览

c# - Activator.CreateInstance:无法从程序集中加载类型

我正在尝试在我的项目中创建在插件 .dll 中实现的类的实例以进行类型发现。我收到了这个例外:

无法从程序集“SquidReports.DataCollector.Plugin.BES,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null”加载类型“Action”。

这是我正在使用的确切方法签名: https ://msdn.microsoft.com/en-us/library/d133hta4(v=vs.110).aspx

换句话说,我试图根据程序集名称和类名生成对象,如下所示:

这里要注意的一个重要部分是,我使用的是程序集的“短”名称,而不是“全”名称(包括版本、文化和 PublicToken)。但是,MSDN 明确指出:

'assemblyName' 可以是以下任意一种: 程序集的简单名称,没有路径或文件扩展名。

  • 例如,您将为路径和名称为 .\bin\TypeExtensions.dll 的程序集指定 TypeExtensions。

  • 已签名程序集的全名,由其简单名称、版本、文化和公钥令牌组成;例如,“TypeExtensions,Version=1.0.0.0,Culture=neutral,PublicKeyToken=181869f2f7435b51”。

具体来说,我正在尝试创建在程序集“SquidReports.DataCollector.Plugin.BES”中定义的“Action”类的实例。我在我试图创建实例的完全相同的 *.cs 文件的顶部明确将此程序集引用为using指令。

我从以前的问题/答案中尝试了以下建议:

清理您的解决方案,重新构建并重试这似乎适用于某些 ASP.NET 项目,但这是普通的旧控制台应用程序。

检查配置文件中引用的程序集再次,这是一个简单的控制台应用程序,仅在同一解决方案的不同项目中使用 GAC 和库

1. 确保程序集位于正确的工作目录中:

我们到了...

就在那儿!!!

2.确保程序集与磁盘上的版本相同

是的...

看起来一样

3.最后推荐使用fuslogvw.exe。

我没有使用该工具的经验,但我确实发现了一件事很奇怪。在运行调试会话时,我的程序集的长名称和短名称版本都出现了:

嗯……

我看了两个日志。

简称版本似乎确实会产生一些警告:

=== 预绑定状态信息 ===

LOG:DisplayName = SquidReports.DataCollector.Plugin.BES Partial)警告:为程序集提供了部分绑定信息:

警告:程序集名称:SquidReports.DataCollector.Plugin.BES | 域 ID:1

警告:仅提供部分程序集显示名称时会发生部分绑定。

警告:这可能会导致活页夹加载不正确的程序集。

警告:建议为程序集提供完全指定的文本标识,

WRN:由简单的名称、版本、文化和公钥标记组成。

警告:有关此问题的详细信息和常见解决方案,请参阅白皮书http://go.microsoft.com/fwlink/?LinkId=109270

...但它以成功加载而告终,并且清楚地提到了我在正确位置的程序集:

日志:正在尝试下载新的 URL 文件:///C:/Source/C#/SquidReports/SquidReports.DataCollector/bin/x86/Debug/SquidReports.DataCollector.Plugin.BES.DLL。

长名称版本的日志不包含可疑消息。

还有什么想法吗?

编辑:这是 Action 类的最小定义。它纯粹是一个模型级。

ICollectible 接口和 [Key] 属性是另一个程序集的一部分。不知道会不会有效果?

编辑 2:正如 Erik 在下面指出的那样,显然我也对这个 OTHER 程序集进行了完全相同的检查。

0 投票
1 回答
395 浏览

c# - EXE(加上依赖的DLL)复制到临时文件夹并启动仍然从原始文件夹加载DLL

我有一个主应用程序,它使用单独的“包安装程序”应用程序在更新版本可用时自行更新。此更新将包括主应用程序、所有 DLL 依赖项以及包安装程序本身。这个过程是这样的:

  1. 主应用检测到版本升级可用
  2. 主应用程序将包安装程序 EXE 复制到临时文件夹,以及它所依赖的 DLL 和它们所依赖的 DLL。换句话说,运行包安装程序所需的最少组件被复制到临时文件夹。
  3. 主应用程序使用 Process.Start 从 temp 文件夹运行 Package Installer
  4. 主应用程序关闭
  5. 包安装程序将新的 EXE 和 DLL 复制到 app 文件夹中
  6. 包安装程序再次启动主应用程序
  7. 包安装程序关闭

由于包安装程序无法覆盖正在使用的文件,步骤 5 总是失败。这些文件是包安装程序本身从 app 文件夹加载的 DLL 。这些是对包安装程序没有直接或间接引用的 DLL。

我已经验证(使用 Windows 资源监视器)它是从应用程序文件夹加载 DLL 的包安装程序(并且只有那个 EXE)。我还仔细检查了 Package Installer 项目没有直接或通过另一个 DLL 对这些 DLL 的引用。我还验证了 Package Installer 从 temp 文件夹加载了它所依赖的 DLL(上面提到的 3 个)。

最后,我尝试在运行 Package Installer 之前将整个应用程序(每个 EXE 和 DLL)复制到 temp 文件夹中,但即便如此,它仍然会从 app 文件夹中加载一些 DLL(这次不是上面提到的那些,而是第 3 方 DLL)。

发生了什么,我能做些什么来抑制额外 DLL 的加载?

0 投票
1 回答
65 浏览

c# - 应用进程#1 能否直接引用同一台机器上的应用进程#2 中的公共静态对象(作为服务运行)?

我有一个 .NET 应用程序,它既可以作为控制台应用程序运行,也可以作为 Windows 服务运行(取决于启动参数)。

这里的想法是让一个实例作为控制台应用程序运行,以充当在同一台机器上作为服务运行的另一个实例的 UI。换句话说,实例#1 可以检查和控制实例#2 的状态。两个实例都从相同的物理文件运行 - 只有一个应用程序安装。

我需要对应用程序进行最少的更改来完成此操作,例如不创建 WCF 服务层(需要访问很多方法),所以我想知道控制台应用程序是否有可能获得直接代码- 对服务应用程序中公共静态对象的代码引用。

我想要访问的公共静态对象位于 EXE 本身中,但如果需要,可以将其移动到应用程序加载的程序集中。

听起来 .NET Remoting 可能是一个解决方案,但它已停产。还有另一种可能吗?

0 投票
3 回答
2283 浏览

nunit - TeamCity NUnit 运行器因 x86 - x64 - MSIL 差异而失败

我有一堆项目的解决方案,其中一些还有测试项目。这些都是为Any CPU平台编译的。

在 TeamCity 中,我有一个 NUnit 2.6.4 的构建配置,我在其上指定Platform: auto (MSIL)Version: 4.0.

当我运行构建时,测试失败并显示以下消息:

更奇怪的是,当我刚刚关闭“首先运行最近失败的测试”(并且没有改变任何其他内容)时,我得到了以下信息:

请注意,在一种情况下,跑步者是 x86,而在另一种情况下是 x64。在这两种情况下,他们都没有成功加载为 MSIL 编译的程序集。

我认为这里的构建设置有些问题,但是什么?

0 投票
1 回答
772 浏览

powershell - 为什么从 PowerShell 调用 F# 代码时会出现 MissingMethodException?

我正在尝试使用 PowerShell 调用一些使用 Akka.Net 演员的 F# 代码。

F# 代码在单元测试和从 F# 解释器运行时工作正常,但是当我从 PowerShell cmdlet 调用相同的代码时,我得到以下异常:

我尝试[Nessos.FsPickler.BinarySerializer]::new.OverloadDefinitions在该 PowerShell 会话中运行以检查 PS 虽然可用的方法,但我得到:

我注意到的第一件事是 PowerShell 显示的版本采用 FSharpOption[bool] 而不是 FSharpOption[Boolean]。我尝试修改 Akka.FSharp 代码以明确传递一个选项,但这似乎没有帮助。

我正在使用 FSharp.Core 4.0.0.1(其他链接建议 3.0 有问题)。

有没有人见过类似的东西?

即使是关于在哪里寻找问题的建议也会有所帮助,我不确定问题是出在 PowerShell、F# 还是 Akka.Net 上。

0 投票
1 回答
533 浏览

c# - 创建或寻找 fuslogvw.exe 的替代方案,即 Fusion Assembly Binding Log Viewer

Assembly Binding Log Viewer 有相当多的错误(例如,它通常不会清空日志)并且功能很短(搜索、排序、过滤几乎都可用)。

所以我想知道是否

  • 现有的替代方案存在
  • 以某种方式在全球范围内挂钩 assemblyresolve 事件是可能的,所以我可以自己做
  • 微软已经在某处发布了源代码,我们可以分叉它

如果没有第二个选项,我知道您可以相对简单地创建一个 CLR Host 实现(尽管这并不简单),但如果您需要的只是比现有 Fusion 日志查看器更细粒度的控制,这似乎有点过头了。

请注意,我已经看到了这个答案,但这似乎没有回答这个问题。


回答一些评论:

我知道程序集重定向、事件AssemblyResolveAssemblyLoad事件,但第一个只能用作最后的手段(探测链中的最后一个),第二个只会在加载程序集后触发。既不能用于您自己的其他进程,也不能显示整个探测过程。

我注意到使用 RyuJIT 时,由于编译和加载编译后的 IL 的方式不同,某些绑定看起来略有不同,顺序也不同。虽然我已经能够研究和解决绑定问题,但我非常不喜欢fuslogvw.exe作为一种耗时(尽管是一种有用且有用的工具)的工具。因此,我开始(相当徒劳)寻找更好的工具来监控探测过程。

0 投票
0 回答
369 浏览

c# - 是否可以在单个 Windows 服务上使用多个版本的 protobuf-net?

我们的应用程序使用了一个相当新的 protobuf-net(版本 2.0.0.668),我正在尝试使用旧版本的 protobuf-net(版本 1.0.0.282)集成到另一个具有客户端库的系统。是否可以在同一个 Windows 服务上使用程序集解析器并排使用库?我知道这些版本之间在序列化程序方面存在重大变化,并且谷歌在版本之间有单独的 protobuf 协议重大变化。

我尝试使用程序集解析器方法,因为我们希望通过退出进程并通过线路为每个客户端调用进行调用来减少调用此客户端库的开销。我想让它并排工作。

即使组装解析器就位(详情如下)。我在需要旧 protobuf 的库上调用了 Assembly.Load,它似乎获得了新版本。即使我没有绑定重定向。我还在项目文件中专门指定了禁用绑定重定向的自动生成。

为什么即使我指定了对项目的特定版本引用以使用版本 1.0.0.282,完全隔离的项目仍默认使用新版本的 protobuf?最终结果是我无法在需要 protobuf.net 版本 1.0.0.282 版本的库上成功序列化 protobuf 消息。

我有不使用 GAC 的限制,也不能创建另一个服务来将对旧版本客户端库的调用包装在另一个服务上,这使得它因进程退出而成为一个非常昂贵的调用。

我的项目结构如下

解决方案 |_WindowsService - 引用 DLL LibraryA 和 DLLLibraryB |_DLL_LibraryA - 引用 protobuf 2.0.0.668 和 DLL_LibraryB |_DLL_LibraryB - 引用 protobuf 1.0.0.282 和 DLL_ThirdpartyClient

DLL_LibraryA 和 DLL_LibraryB 项目是通过引用 protobuf.net 来设置的,以使用特定版本而不是复制本地。

我在 WindowsService 项目上创建了一个构建事件,以便在触发 appdomain resolveassembly 事件时将 bin->ThirdParty->protobuf-net->{version} 文件夹中的 protobuf-net 文件复制到程序集加载器中。

即使我完全隔离程序集并将项目配置设置为禁用绑定重定向的自动生成(禁用自动绑定重定向)。我的程序集加载器只被调用版本 2.0.0.668。

有趣的一件事是,我们的解决方案利用 MEF 进行组合和依赖注入。我想知道它是否有任何影响。同样基于我的解决方案的结构,DLL_LibraryA 依赖于 protobuf-net 2.0.0.668,并且通过 DLL_LibraryB 的依赖关系不直接地依赖于 protobuf-net 1.0.0.282。在这种情况下 clr 做了什么?有没有办法在不退出流程的情况下成功地做到这一点?是因为 CLR 总是决定让我加载最新版本的依赖关系的混合吗?

任何信息将不胜感激。

详情在这里:

  1. 创建版本解析器 - 使用程序集解析器使用并排程序集加载 x64 或 x32 版本的 DLL

    /li>
  2. 在 Windows 服务程序中调用解析器 -

    静态程序(){ AppDomain.CurrentDomain.AssemblyResolve += VersionResolver; }

0 投票
1 回答
60 浏览

visual-studio-2013 - 无法在 Visual Studio 2013 扩展中加载 EntityFramework.dll 5.0.0.0

我正在编写一个依赖于 EntityFramework 5.0.0.0 的 Visual Studio 扩展。我在我的项目中包含了 EntityFramework。当我安装我的扩展程序时,我的扩展程序的 DLL 出现在 VS 扩展文件夹中,并且 EntityFramework.dll 也随之出现。

但是,当我在 Visual Studio 2013(更新 5)中运行我的扩展时,它无法加载 EntityFramework:System.IO.FileNotFoundException: Could not load file or assembly 'EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The system cannot find the file specified.

查看 Process Monitor,我看到当我运行我的扩展程序时,VS2013 尝试从不同的路径加载 EntityFramework,它具有不同的版本 - 4.2。我希望 VS2013 继续搜索 EntityFramework,并在我的扩展程序的文件夹中找到它,就像我的扩展程序中包含的其他 dll 一样,但事实并非如此。

在 VS2015 中,VS 确实设法加载了 EntityFramework 5.0.0.0,但它也是从另一个不同的路径加载的。

为什么VS2013不继续在我的扩展文件夹中搜索EntityFramework?

0 投票
0 回答
145 浏览

c# - 参考程序集的重新分配

我们有一个使用 CSharpCodeProvider 动态生成和编译代码的应用程序。编译的代码使用 Entityframework,因此我们将 Entityframework.dll 的引用传递给编译器。我们随应用程序重新分发的 Entityframework.dll 是为 .net 4.0 构建的。我们还将对 System.ComponenModel.DataAnnotations.dll 的引用传递给编译器。这是对在 GAC 中找到的 dll 的引用。

在 .net 4.0 上运行应用程序时,所有这些都可以正常工作。但是,当在 .net 4.5 上运行时,我们会遇到一个问题,因为 .net 4.0 中的 Entityframework 中的一些属性已被移动到 .net 4.5 中的 System.ComponenModel.DataAnnotations 中。所以我们得到这样的错误:

消息=错误(CS0246):找不到类型或命名空间名称“列”(您是否缺少 using 指令或程序集引用?) - 文件:c:\Generated\DataContext\0rs2sztj.2.cs:14 错误(CS0433):“System.ComponentModel.DataAnnotations.Schema.ColumnAttribute”类型存在于“c:\Users\Steven Segers\AppData\Local\Temp\Temporary ASP.NET Files\vs\69fafaea\17b01629\assembly\dl3 \95fc97d4\5bdae37d_7c05d101\EntityFramework.DLL' 和 'c:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.ComponentModel.DataAnnotations\v4.0_4.0.0.0__31bf3856ad364e35\System.ComponentModel.DataAnnotations.dll' - 文件:c :\Generated\DataContext\0rs2sztj.2.cs:14

据我所知,有两种方法:

  1. 将 .net 4.0 的 System.ComponenModel.DataAnnotations 的参考程序集传递给编译器。这里的问题是这个参考程序集需要存在于目标机器上。为了适应这种情况,我们需要要求客户在他的服务器上安装 Windows SDK,或者将参考程序集与我们的应用程序一起分发。我发现前者是一个相当不受欢迎的要求,我不确定是否允许后者。
  2. 确保我们将面向运行时 .net 版本的 Entityframework.dll 传递给编译器。我不确定实现这一目标的最佳方法是什么。