通过COM / Interop和.NET应用程序调用.NET程序集时,是否有不同的加载上下文用于引用的程序集?

时间:2011-04-20 15:36:33

标签: .net com-interop appdomain

我使用COM Interop从VB6应用程序调用托管代码,后者本身随后在创建新的AppDomain后从另一个托管程序集调用代码。这个新的AppDomain实际上是实例化正在使用的对象的实例。

为了让这个更容易理解,这些是玩家:

  • VB6应用程序: LegacyApp.exe
  • 包含所有.NET程序集中使用的界面信息的程序集: MeatyInterfaces.dll
  • COM互操作.NET程序集:InteropAssembly.dll
    • 本大会直接引用MeatyInterfaces.dll
  • InteropAssembly.dll使用的程序集: MeatyImplementations.dll
    • 此程序集直接引用MeatyInterfaces.dll,并实现这些接口
    • 使用实现“MeatyImplementations.ExampleImplementation”实现接口“MeatyInterfaces.IExampleInterface”

为了简化这个过程,基本上我们创建一个AppDomain,并在LegacyApp.exe调用的InteropAssembly.dll代码中实例化新的AppDomain中的ExampleImplementation:

AppDomainSetup domainSetup = GetExampleSetupInfo();
AppDomain domain = AppDomain.CreateDomain(domainSetup.ApplicationName, AppDomain.CurrentDomain.Evidence, domainSetup);
ObjectHandle handle = domain.CreateInstance("MeatyImplementations.dll", "MeatyImplementations.ExampleImplementation");

一旦我们有了这个句柄,我们就会尝试打开它并将其转换为ExampleExmplementation实现的IExampleInterface。

MeatyInterfaces.IExampleInterface initializer = (MeatyInterfaces.IExampleInterface) handle.Unwrap();

这会引发以下异常:

Exception: "System.InvalidCastException"
Message: "Unable to cast transparent proxy to type 'MeatyInterfaces.IExampleInterface'"

奇怪的是,如果我们运行这个确切的代码,但从Managed(.NET)应用程序开始,它的工作完全正常。

以下是我所知道的:

  • 我知道有两种可以加载程序集的上下文:Load和LoadFrom,后者对DLL的位置很敏感。
  • 我知道将一个对象从一个Load Context转换成另一个对象似乎是导致这个问题的最常见原因(事实上,我唯一能找到相当详尽的搜索)
  • 我知道,如果我按照此处推荐的那样覆盖AssemblyResolve事件(http://west-wind.com/weblog/posts/601200.aspx),它会解决问题,这进一步告诉我(尽管我没有实质证据)InteropAssembly.dll必须加载MeatyInterfaces .dll在与上面显示的方式使用时不同于MeatyImplementations.dll的加载上下文中。

所以这是我不明白的......如果有人能提供澄清,我将非常感激:

我不明白为什么加载上下文会有所不同,具体取决于我是通过VB6 App(使用COM Interop)与.NET App使用InteropAssembly.dll,还是整个Load的概念上下文一直是一个红色的鲱鱼,他的修复只是巧合地解决了我的问题。

1 个答案:

答案 0 :(得分:0)

我找到了答案:

我正在错误地查看Fusion Log:

InteropAssembly.dll在LoadFrom上下文中加载,但这不是问题。问题是,当InteropAssembly.dll试图加载MeatyInterfaces.dll时,它无法找到它:MeatyInterfaces.dll位于InteropAssembly.dll所在的bin文件夹中,但它没有找到它:它正在寻找在LegacyApp.exe的应用程序路径中。

.NET App基本上是巧合的:这些程序集作为构建过程的一部分被添加到.NET App的bin文件夹中,因此它在它正在检查的文件夹中具有所需的所有依赖项。

我看到的异常导致我进入Load上下文路径基本上是一个巧合:加载依赖项失败并没有触发异常,直到第一次使用它,这恰好是发生转换的地方:在绝大多数情况下,它引发的异常似乎是由不匹配的负载上下文引起的。

F7U12

是的,这就是原因:我现在已经学到了很多困难,虽然可以通过COM Interop从调用应用程序的路径(或GAC)以外的位置加载程序集,但程序集的依赖性仍然需要在应用程序的路径中。 D'哦。