COM基础之COM在注册表中的相关键值及其意义

COM基础之COM在注册表中的相关键值及其意义

 

COM在系统注册后,会在系统注册表中产生相应的表项。与COM相关的几个常见概念包括:

1. 类型库 Type Library

COM是一种基于独立于开发语言的编程模型。因此在描述COM功能和接口的时候采用了与编程语言无关的接口描述语言(IDL)来编写接口的抽象定义,该接口定义文件(*.IDL)经过Platform SDK自带的Microsoft IDL编译器编译之后将生成相应的头文件、类型库等。

如下是一个简单的类型库定义文件(OOPCOM.idl)

InterfaceClass就不用多说了。

需要说明的是,在系统中为了注册一个COM,采用了用GUID(16Bytes)来描述其相关内容的方法,包括类型库,COM接口定义和COM Class的定义。

// OOPCOM.idl : IDL source for OOPCOM.dll

// This file will be processed by the MIDL tool to

// produce the type library (OOPCOM.tlb) and marshalling code. 

import "oaidl.idl";

import "ocidl.idl";

       [

              object,

              uuid(DB20D9BF-FAA4-4D23-9243-19860EB4482A),

              dual,

              helpstring("ISimpleClass Interface"),

              pointer_default(unique)

       ]

       interface ISimpleClass : IDispatch

       {

              [id(1), helpstring("method HelloWorld")] HRESULT HelloWorld([out,retval]BSTR *result);

       };

 

[

       uuid(FE0FAA57-2E27-425F-9FA3-518E73F729FB),

       version(1.0),

       helpstring("OOPCOM 1.0 Type Library")

]

library OOPCOMLib

{

       importlib("stdole32.tlb");

       importlib("stdole2.tlb");

 

       [

              uuid(1CF4A019-A754-44F1-B164-047A3F0AC184),

              helpstring("SimpleClass Class")

       ]

       coclass SimpleClass

       {

              [default] interface ISimpleClass;

       };   

}; 

2. COM Interface

3.   COM Class

4.    Application ID &Name

 

当我们编写好一个COM并将其在系统中注册之后,对于初学者来说,这些注册表项到底位于Register中的什么位置,系统是如何通过这些注册表项在Runtime时候找到某个COM的,可能有点一头雾水。其实,总的来说,系统是通过GUID来查找每个对象的,比如TypeLib,Interface和Class都有其相应的GUID(16bytes的字符串)

下面简单列出这些用来描述COM的相关表项在注册表中的位置及其意义:

表项一:COM Interface

Path :  HKEY_CLASSES_ROOT/Interface/[X]

或者: HKLM /Software / Classes/Interface / [x]

1

在以上的OOPCOM.idl,我们看到其Inferface ID (IID)为DB20D9BF-FAA4-4D23-9243-19860EB4482A,其在Register中的位置如上图1所

COMInterface表项中包含
1. ProxyStubClsid
:该键值的具体内容请参考下图2

2. ProxyStubClsid32 :该键值的具体内容参考下图2。该键值与ProxyStubClsid相同值。

3. TyleLib: 与该interface相关的COM 类型库定义

Interface中,有关ProxyStubClsidProxyStubClsid32所指向的CLSID值如下图2所示:

 

2

 那么,这个ProxyStubClsid键值和ProxyStubClsid32起什么作用呢?这就需要对COM client和COM service是如何进行通讯和数据交换的有所了解。

我们知道,当COM client和COM Server application不在同一个进程地址空间时,COM会建立一个客户端的proxy和server端的stub。例如当client调用CoCreateInstance()时,在服务器将接口指针返回给COM之后,COM将接口指针返回给client之前,COM为指定的接口创建proxy和stub并将指向proxy的指针返回给client。我们把类似这样的过程叫做Marshaling (汇集)。

开发人员可以implement IMarshal这个interface来支持自定义的Marshaling。而如果对象不支持自定义Marshaling,则COM使用proxy和stub程序执行标准Marshaling,因此COM必须从注册表中获得提供proxy和stub程序生成器的DLL的CLSID。这就是我们为什么ProxyStubClsid(32)的意义所在。

一般来说,如果开发的COM支持自动化技术,即实现了IDispatch interface(支持解释型语言的调用,如vbscript等),则其Marshaling的dll一般为以上所示的oleaut32.dll (16bit系统则为ole2disp.dll)。而如果其不支持该技术,则其Marshaling的Dll一般为ole32.dll

 

表项二:COM Class

Path : HKEY_CLASSES_ROOT / CLSID/ [X]

或者: HKLM /Software / Classes/CLSID / [x]

 by default,在CLSID下面包含以下一个键值(如上图所示)

1. LocalServer32

2. ProgID

3.TypeLib

4.Programmable (omitted)

 

下面对每个键作简要解释:

LocalServer32:

该键用来指定运行在进程外的COM Server Application的.EXE文件path。与之相似的一个表项是:InprocServer32。我们知道,COM运行模式有2种,一种为进程内模式,即COM与Client在同一个进程内存之内,运行在这种模式下的COM必须只能为*.dll,指定其具体COM module的path的时候,即用InprocServer32来指定;另外一种是Out of Process(OOP),即Client和COM Server Application位于不同的Process地址空间,而这种COM必须为*.EXE,指定其具体COM module 的path时候,即用LocalServer32来指定。

而这两种模式下的COM调用过程也不尽相同。

      1.服务器为*.dll时,调用过程如下所示:

      2. 当服务器为*.EXE 时,其过程如下所示:

 ProgID:

实际上ProgID和CLSID都是一回事,只不过是2种不同的叫法而已,ProgID可以说是CLSID的nickname吧。相对于CLSID一串16bytes的难以记忆的数字, ProgID显得更为人性化,系统提供了相应API: GetClsIdFromProgid(t_ProgID)  可以实现ProgID和CLSID之间的互换。

TypeLib:

不用多讲了, 该键在COM interface键中也出现过,用来指定该COM的类型库文件。

既然在COM Interface和COM class中都出现了Type Libray,那就看看TypeLib 键吧。

 

COM Type Library

Path : HKEY_CLASSES_ROOT/TypeLib/ [X]

 TypeLib的各项键值如上图所示。

 

 

还有一项不太注意的Regeister Entry就是AppID。当我们把COM注册到系统之后,系统会在 HK_ROOT/AppID 下面生成一个指向该COM的AppID Entry。缺省情况下,会使用COM module name作为该Application name,从而使得该COM/DCOM readable.如下图在dcomcnfg.exe中所示,该AppID和一个readable的Application Name对应起来。

COM Application相关注册表项:

 

Path : HKEY_CLASSES_ROOT/AppID/ [X]

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值