【发布时间】:2015-10-23 18:51:16
【问题描述】:
我编写了一个在 COM+ 应用程序中运行的 .Net 组件。该组件继承自 ServicedComponent 并标记为作为服务器进程运行(因为我需要通过多个消费者的激活来维护静态数据)。
使用 RegAsm.exe 完成注册:
c:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe /codebase MyObject.dll
手动创建 COM+ 应用程序,并在创建后添加组件。
如果我从 PHP 实例化我的组件,代码将按预期工作:实例是在组件服务控制台中列出的单独进程中创建的。
<?php
$obj = new COM("MyObject.Sender");
$obj->SendMessage("Hello world");
?>
但是,当我尝试从 .Net 测试可执行文件实例化组件时,我收到“无法创建 ActiveX 组件”异常:
Try
Using gw = CreateObject("MyObject.Sender") 'Exception thrown HERE
Dim gwsender As IMsgSender = gw
gwsender.SendMessage("Hello world")
End Using
Catch ex As Exception
MsgBox(ex.ToString)
End Try
测试可执行文件是一个简单的 WinForm 应用程序。
将调试器设置为在所有异常时停止我能够获得以下 MDA:
名为“MyObject”的程序集是从 'file:///c:/MyObject/bin/Debug/MyObject.dll' 使用 LoadFrom 上下文。使用此上下文可能会导致 序列化、强制转换和依赖的意外行为 解析度。在几乎所有情况下,建议 LoadFrom 避免上下文。这可以通过在 全局程序集缓存或在 ApplicationBase 目录中并使用 显式加载程序集时的 Assembly.Load。
这是我所期望的,因为它是使用 /CodeBase 而不是使用 GAC 注册的。但后来:
显示名称为“MyObject”的程序集未能加载到 ID 为 1 的 AppDomain 的“LoadFrom”绑定上下文。 失败是:System.IO.FileNotFoundException:无法加载文件 或程序集'MyObject,版本=1.0.0.0,文化=中性, PublicKeyToken=92a84ff3d67c82b9' 或其依赖项之一。这 系统找不到指定的文件。
MyObject 组件(如果从 PHP 调用可以完美加载)没有特殊依赖项(仅 .Net)。从 sysinternal 的进程监视器跟踪我看不到任何失败,并且对我的 .dll 的访问是成功的(CreateFileMapping、Load Image 等)。看起来不是文件访问问题,而是框架进行了一些运行时检查。
测试 .net 客户端和 COM+ 组件都是从同一个编译器编译的;所有相关选项看起来都一样(平台设置为 x86,.Net Framework 4)。作为额外的调试措施,我将框架版本记录到组件和测试程序中的文件中,尽管它们是相同的(4.0.30319.34209)。一切都在同一台机器上运行。
Fusion 日志表明运行时尝试直接加载二进制文件(不调用 COM+ 实例)。
出于遗留原因,我需要这种扭曲的交互(.Net-->COM+-->.Net),但我无法使其工作。会发生什么?
【问题讨论】:
标签: .net com-interop remoting com+