zoukankan      html  css  js  c++  java
  • COM在注册表中的相关键值及其意义

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

    概要

    当编写好一个COM并将其在系统中注册之后,这些注册表项到底位于Register中的什么位置,系统是如何通过这些注册表项在Runtime时候找到某个COM的,这些都是诊断COM相关的问题至关重要的信息。总的来说,系统是通过GUID来查找每个对象的,比如TypeLib,Interface和Class都有其相应的GUID(16bytes的字符串)。本文介绍了一个COM在注册后,系统注册表会被写入哪些键值,以及这些键值所代表的意义。

    正文

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

    复制代码
    // 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;
           };    
    }; 
    复制代码

    本文主要介绍以下几个COM相关常见概念:

    1. COM Interface
    2. COM Class
    3. Type Library
    4. Application ID &Name

    COM的相关表项在注册表中的位置及其意义:

    表项一:COM Interface 
    注册表路径 : HKEY_CLASSES_ROOT\Interface\[X] 或者:HKLM\Software\Classes\Interface\[x]

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

    在COM的Interface表项中包含

    1. ProxyStubClsid :该键值的具体内容请参考下图。
    2. ProxyStubClsid32 :该键值的具体内容参考下图。该键值与ProxyStubClsid相同值。
    3. TypeLib: 与该interface相关的COM 类型库定义。

    在Interface中,有关ProxyStubClsid和ProxyStubClsid32所指向的CLSID值如下图所示:

    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 (汇集)。
    开发人员可以实现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
    注册表路径: HKEY_CLASSES_ROOT\CLSID\[X] 或者:HKLM\Software\Classes\CLSID\[x]

    缺省情况下,在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 Library,那就看看TypeLib 键吧。

    表项三: COM Type Library
    注册表路径: HKEY_CLASSES_ROOT\TypeLib\ [X]

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

     

    表项四:COM Application相关注册表项
    注册表路径: HKEY_CLASSES_ROOT\AppID\[X]

    希望以上内容对您有所帮助

    Winston He

     
     
    标签: COMRegistryGUIDInterface
  • 相关阅读:
    IE8使用chrome内核渲染
    JS中的call()方法和apply()方法用法总结(挺好 转载下)
    解决雷达图文字显示不全问题
    echarts legend文字配置多个颜色(转)
    vue中Axios的封装和API接口的管理
    echarts 折线拐点收藏
    echarts 折线图自定义颜色与修改legend颜色
    MUI框架 按钮点击响应不好的问题解决办法
    ECharts将折线变平滑和去掉点的属性
    单例模式——创建型模式01
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3114986.html
Copyright © 2011-2022 走看看