我编写了一个在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”的程序集 '文件:/// C:/MyObject/bin/Debug/MyObject.dll' 使用LoadFrom上下文。使用此上下文可能会导致 序列化,转换和依赖的意外行为 解析度。在几乎所有情况下,建议使用LoadFrom 避免上下文。这可以通过在中安装程序集来完成 全局程序集缓存或在ApplicationBase目录中使用 显式加载程序集时的Assembly.Load。
我的预期是因为它是使用/ CodeBase而不是使用GAC注册的。但那时:
显示名称为“MyObject”的程序集无法加载 'LoadFrom'绑定AppDomain的上下文,ID为1.原因 失败的原因是:System.IO.FileNotFoundException:无法加载文件 或汇编'MyObject,Version = 1.0.0.0,Culture = neutral, PublicKeyToken = 92a84ff3d67c82b9'或其依赖项之一。该 系统找不到指定的文件。
MyObject组件(如果从PHP调用则完美加载)没有特殊的依赖关系(仅限.Net)。从sysinternal的进程监视器跟踪我看不到任何失败,并且对.dll的访问成功(CreateFileMapping,Load Image等)。它看起来不像文件访问问题,而是由框架进行的一些运行时检查。
测试.net客户端和COM +组件都是从同一个编译器编译的;所有相关选项看起来都一样(平台设置为x86,.Net Framework 4)。作为额外的调试措施,我将框架版本记录到组件和测试程序中的文件中,尽管它们是相同的(4.0.30319.34209)。一切都在同一台机器上运行。
Fusion日志表明运行时尝试直接加载二进制文件(不调用COM +实例)。
由于遗留原因,我需要这种扭曲的互动(.Net - &gt; COM + - > .Net),但我不能让它发挥作用。可能会发生什么?
答案 0 :(得分:0)
事实证明,使用RegAsm.exe进行注册不是此操作的正确过程。必须首先将程序集添加到GAC,然后必须使用regsvcs实用程序创建COM +应用程序。否则,.Net根本不会查看COM +目录:
"c:\Windows\Microsoft.NET\Framework\v4.0.30319\regsvcs.exe" MyObject.dll
"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\gacutil.exe" /i MyObject.dll
注意:系统中的实用程序路径可能有所不同。