在 ASP.Net/C# 中调用 DCOM 对象
COM 代表着编写基于组件的系统的方式,但随着 .net 框架的出现,组件开发过程已经变得简单多了。相比 COM ,.net 框架提供了简单得多而且强大得多的服务。之所以我们还需要在 .net 开发中使用 COM/COM+,就是因为我们无法一下子放弃所有的遗留代码,花费巨额成本开发的 COM 组件还没有到完全退隐的时候。同样我们在开发基于 .net 框架的组件的时候,为了兼容过去的应用,依然为其创建了 COM 接口。
使用 DCOM 而不是 .net remoting 还有一个理由,DCOM 提供了基于 TCP/IP 的进程间安全通讯通道,同时 DCOM 可以是任何形式的单一进程(即 Out Of Process, 进程外 COM 组件),甚至是系统服务进程也可以。
.net 在这方面具有优良的兼容性,我们可以:
在 .net/C#/VB.net 编写的托管代码中调用 vc++ 6.0 或其他任何语言编写的 COM/COM+/DCOM 组件;
也可以在 vc++ 6.0 编写的代码中调用 .net/C#/VB.net 编写的 COM/COM+/DCOM 组件。
具体的使用方法 MSDN 中有详细的描述。
但是当我尝试在 ASP.Net/C# 程序中使用一个同样是 .net/C# 编写的 DCOM 时遇到了一点障碍。最初我是尝试这样使用该 DCOM 组件的。在 ASP.Net 工程中添加引用(Add Reference), 当我在 COM 栏中找到我的组件 cscom 添加引用时,发生错误,由于本身是托管代码编写的被注册为 cscom.tlb,所以 VS2008 无法再次将其转换并引入到工程中。只能以 Browse 浏览方式直接引用 cscom.exe 文件,添加引用成功,直接在代码中 using cscom; 然后尝试创建 cscom.CMyClass 实例,但是 new 失败了,返回一个空对象,DCOM Server 进程也没有如预期的被运行起来。查阅了很多资料作了几种尝试都没有成功。
仔细的想了想,这种引用方式是早绑定的,cscom 被作为一个 Assembly 装载而不是 DCOM 方式, 而且我并不清楚 .net 到底是如何处理被引用进来的 Assembly,后来我的尝试解决了这个问题。
正确的使用方法:
对 cscom 对象进行显式的晚绑定。由于.net 使用普通 COM 组件是非常方便的(添加引用),所以晚绑定的方式使用得非常少,但在传统 c++ 代码中确实普遍使用的,这段代码在 .net 中同样比 c++ 中来得简洁:
Type objCSCom = Type.GetTypeFromCLSID(new Guid("{f681abd0-41de-46c8-9ed3-d0f4eba19891}")); Object objLateBound = Activator.CreateInstance(objCSCom); Object[] arrayInputParams = {"888***"}; String str = (String)objCSCom.InvokeMember( "GetDateTime", System.Reflection.BindingFlags.Default | System.Reflection.BindingFlags.InvokeMethod, null, objLateBound, arrayInputParams);
访问这段代码所在的页面,cscom.exe 进程在服务器上以 NETWORK SERVICE (运行 IIS 的帐户)帐户运行起来,页面上正确显示从 cscom 对象中返回的值。

