C#创建COM的实例

前言
C#总的来说不错,Framework也提供了比较丰富的类库,基本上能够满足大部分的需要。但是应用程序难免要和遗留系统打交道,比如说:API函数或者COM组件。
C#在Framework环境内部怎么玩都挺好,一旦要和Framework之外的组件函数打交道就需要作一些手脚了。这里主要对在C#中调用COM组件经常遇到的集中情况进行说明。
 
1、引用一个COM组件,通过New创建
大部分情况下调用COM组件是非常简单的时候,在工程中引用COM组件对应的文件就行了,“Project->References->Add Reference...”。
我们会发现自动生成了一个interop.xyz.dll之类的文件,这个文件中包含了一大堆定义,它其实就是将COM组件中的Interface、CoClass、
Enum和Const等重新包装成为符合Framework的形式,接下来我们就可以在程序中直接使用了。DotNet Framework有一个配套的工具tlbimp.exe,
可以自己手动进行转换。
例如在Windows XP SP2下,在工程中引用了%System32%/hnetcfg.dll后,就可以直接写这样的代码:
    NETCONLib.NetSharingManagerClass iManager = new NETCONLib.NetSharingManagerClass();
iManager就是一个类的实例,可以相调用Framework类库中其他的类实例一样使用。
 
如果是控件,也差不多,在工具栏上执行“Add/Remove Items...”的动作,选择控件对应的DLL或者OCX,然后就可以像Framework下的控件一样使用。
控件通常会生成两个文件:axinterop.xyz.dll,包含ConnectionPoint的信息;interop.xyz.dll,CoClass和Interface等的定义,通常不需要关心这些细节。
DotNet Framework有一个配套的工具aximp.exe,也可以自行转换。
 
2、不引用COM组件进行调用
此外有些组件只暴露接口,没有暴露实现接口的CoClass或者没有暴露实现接口的CoClass的构造函数,这个时候我们没有办法通过new的方式创建实例,就比如说上面的例子。
同样引用hnetcfg.dll,其中NetFwTypeLib命名控件下只有接口的定义,这个时候下面的代码运行时会产生找不到构造函数的错误:
   NetFwTypeLib.INetFwMgr  iFwMgr = new NetFwTypeLib.INetFwMgr(); // Error!
没有办法了么?当然不是。COM组件实现的接口如果可以被外界创建,即便是不暴露CoClass,也可以通过ClassFactory的方式去创建实例。
我们知道VB和VBS等脚本语言有一个特性,叫后期绑定,就是不引用类型库,直接通过CreateObject创建对象并且使用。C#中也有类似的方法,通过调用Activator.CreateInstance实现等同CreateObject的功能。具体步骤如下:
    Type    typFwMgr = null;
    NetFwTypeLib.INetFwMgr    iFwMgr = null;
    ...
    typFwMgr = Type.GetTypeFromCLSID(new Guid("{304CE942-6E39-40D8-943A-B913C40C9CD4}"));
    iFwMgr = (NetFwTypeLib.INetFwMgr) Activator.CreateInstance(typFwMgr);
在这种情况下可以不引用类型库,直接通过Type.InvokeMember去调用方法,参考代码如下:
    Type    typFwMgr = null;

    ...
    typFwMgr = Type.GetTypeFromCLSID(new Guid("{304CE942-6E39-40D8-943A-B913C40C9CD4}"));
    Object objFwMgr = (NetFwTypeLib.INetFwMgr) Activator.CreateInstance(typFwMgr);
    typFwMgr = objFwMgr.GetType();
    typFwMgr.InvokeMember(...);
这样的方式就很灵活了,C#一样可以用后期绑定的方法是用COM组件,在调用具体方法时会麻烦一点。
 
3、在另一个AppDomain创建COM实例
还有一种情况,应用程序中可能有多个AppDomain,希望在另一个AppDomain上创建一个实例。AppDomain为应用程序执行提供了独立的运行空间,通常Remoting的应用的时候有用。
这里稍稍提一下调用方式:
   AppDomain newDomain = AppDomain.CreateDomain("Test");
   System.Runtime.Remoting.ObjectHandle objhdlManager = newDomain.CreateComInstanceFrom("interop.netconlib.dll","NETCONLib.NetSharingManagerClass");
   NETCONLib.NetSharingManagerClass iManager = (NETCONLib.NetSharingManagerClass) objhdlManager.Unwrap();
和当年COM+ Component的应用有几分相似亚。

SoftWareDeveloper QQ群讨论 48735085

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值