Win32:注册ActiveX控件所需的注册表项?

时间:2008-11-12 17:00:35

标签: winapi com activex registry

我需要编写调用DllRegisterServer时运行的代码。即当有人打电话时:

regsvr32 myActiveX.ocx

我正在尝试找到所需注册表项的最终列表(而不仅仅是我可以通过注册表拼写一起拼凑起来)。

到目前为止,我的探险队已经找到了:

HKEY_CLASSES_ROOT
   \MyCoolLibrary.MyCoolControl
      \Clsid
         (default) = "{myClassId}"
   \CLSID
      \{myClassId}
         \Control
         \InprocServer32
            (default) = "c:\foo\myActiveX.ocx"
            ThreadingModel = "Apartment"
         \MiscStatus
            \1
               (default) = 205201
         \ProgID
            (default) = "MyCoolLibrary.MyCoolControl"
         \ToolboxBitmap32
            (default) = "c:\foo\myActiveX.ocx,1"
         \TypeLib
            (default) = "{myTypeLibraryGuid}"
         \Verb
            \0
               (default) = "Properties,0,2"
         \Version
            (default) = "1.0"
   \TypeLib
      \{myTypeLibraryGuid}
         \1.0
            (default) = "MyCoolLibrary.MyCoolControl"

现在,关注点:   - Control文件夹包含什么?它的存在是否表示控制?   - 什么是205201的MiscStatus呢? 205202会做什么呢?   - 什么是动词“属性,0,2”?哪个是“属性,0,0”和“属性,0,1”?

换句话说,我正在寻找文档。

7 个答案:

答案 0 :(得分:9)

到目前为止我所知道的。 COM根据它的 clsid 创建一个对象。这是一个唯一标识该类的guid。

HKEY_CLASSES_ROOT
   \Clsid
      \{AE8530CF-D204-4877-9CAB-F052BF1F661F}

然后该类用于创建对象。 COM现在需要知道DLL在哪里容纳COM对象。在我的特定情况下,暴露COM对象的“服务器”是一个DLL,并且将“正在进行中”。然后我们通过添加:

将COM指向“进程中”dll
HKEY_CLASSES_ROOT
   \Clsid
      \{AE8530CF-D204-4877-9CAB-F052BF1F661F}
         \InprocServer32
            (default) = "c:\foo\myActiveX.ocx"

COM还需要知道COM服务器对象支持的线程模型。最简单,最常见,本例中使用的是“Apartment”线程模型:

HKEY_CLASSES_ROOT
   \Clsid
      \{AE8530CF-D204-4877-9CAB-F052BF1F661F}
         \InprocServer32
            (default) = "c:\foo\myActiveX.ocx"
            ThreadingModel = "Apartment"

接下来是ProgID。这与DNS用于将友好名称转换为IP的方式类似。在这里,我们将友好名称"MyCoolLibrary.MyCoolControl"变成丑陋的clsid "{AE8530CF-D204-4877-9CAB-F052BF1F661F}"

HKEY_CLASSES_ROOT
   \Clsid
      \{AE8530CF-D204-4877-9CAB-F052BF1F661F}
         \InprocServer32
            (default) = "c:\foo\myActiveX.ocx"
            ThreadingModel = "Apartment"
HKEY_CLASSES_ROOT
    \MyCoolLibrary.MyCoolControl
       \Clsid
           (default) = "{AE8530CF-D204-4877-9CAB-F052BF1F661F}"

现在有人可以要求

MyCoolLibrary.MyCoolControl

和COM可以将其转换为ClassID

{AE8530CF-D204-4877-9CAB-F052BF1F661F}

一旦COM拥有了clasid,它就可以在HKCR\Clsid\{AE8530CF-D204-4877-9CAB-F052BF1F661F}下的注册表中查找真实信息。

为了好玩,ProgID被添加到Clsid部分,以便人们可以知道这个类是什么:

HKEY_CLASSES_ROOT
   \Clsid
      \{AE8530CF-D204-4877-9CAB-F052BF1F661F}
         \InprocServer32
            (default) = "c:\foo\myActiveX.ocx"
            ThreadingModel = "Apartment"
         \ProgID
             (default) = "MyCoolLibrary.MyCoolControl"
HKEY_CLASSES_ROOT
    \MyCoolLibrary.MyCoolControl
       \Clsid
           (default) = "{AE8530CF-D204-4877-9CAB-F052BF1F661F}"

接下来是类型库。对于进程中的任何内容,这主要是 un ,但如果COM对象位于另一个“单元”中,则需要对函数参数进行编组。如果COM具有定义所有类方法的类型库,则会自动为您执行此操作。

clsid部分指向适当的类型库,并添加了TypeLib键:

HKEY_CLASSES_ROOT
   \Clsid
      \{AE8530CF-D204-4877-9CAB-F052BF1F661F}
         \InprocServer32
            (default) = "c:\foo\myActiveX.ocx"
            ThreadingModel = "Apartment"
         \ProgID
             (default) = "MyCoolLibrary.MyCoolControl"
         \TypeLib            
             (default) = "{17A5A3D4-439C-4C2A-8AB4-749B7771CDE1}"
HKEY_CLASSES_ROOT
    \MyCoolLibrary.MyCoolControl
       \Clsid
           (default) = "{AE8530CF-D204-4877-9CAB-F052BF1F661F}"

有关此类型库的信息也存储在注册表中,但是通过调用RegisterTypeLib为我们添加了这些键。但它会为我们添加类似的键:

HKEY_CLASSES_ROOT
   \Clsid
      \{AE8530CF-D204-4877-9CAB-F052BF1F661F}
         \InprocServer32
            (default) = "c:\foo\myActiveX.ocx"
            ThreadingModel = "Apartment"
         \ProgID
             (default) = "MyCoolLibrary.MyCoolControl"
         \TypeLib            
             (default) = "{17A5A3D4-439C-4C2A-8AB4-749B7771CDE1}"
HKEY_CLASSES_ROOT
    \MyCoolLibrary.MyCoolControl
       \Clsid
           (default) = "{AE8530CF-D204-4877-9CAB-F052BF1F661F}"
HKEY_CLASSES_ROOT
    \TypeLib
        \{AE8530CF-D204-4877-9CAB-F052BF1F661F}
           \1.0
              (default) = "My Cool ActiveX Library"
           ...

现在我们进入了一些棘手的东西,希望使ActiveX控件工作所需的东西。

An MSDN article states您必须添加虚拟可编程键以指示它是ActiveX控件:

HKEY_CLASSES_ROOT
   \Clsid
      \{AE8530CF-D204-4877-9CAB-F052BF1F661F}
         \Programmable

但是this MSDN Library page表示关键字是控制,而不是可编程 - 并且没有可编程密钥。

但这并不能阻止某些ActiveX使用Control,有些使用Programmable,有些使用两者。

我找不到任何其他需要的东西。

那么,有人能找到一些明确的文件吗?

答案 1 :(得分:5)

Larry Osterman提供了一个很好的起点:

  

“货运崇拜”的很大一部分   这就是事实   是一组令人眼花缭乱的注册表   可以为COM设置的设置   对象,并不清楚哪个,如果   任何申请。所以我试图打下去   一系列可以提供帮助的文章   人们决定他们需要什么   集。

- What registry entries are needed to register a COM object.

总结:它取决于您需要使用对象的场景。最基本,绝对必要的设置是HKEY_CLASSES_ROOT\CLSID\<clsid>\中的默认值和ThreadingModel,但大多数时候您需要ProgIDs和AppID也是。

答案 2 :(得分:5)

通过Kraig Brockenschmidt查找/借用/窃取Inside OLE 2的副本。它像世界一样古老(也和我约会: - ))

这里也是上面提到的注册表项的a high-level overview

阅读Larry Osterman的blog post以获取更多指示。

查看MSDN ActiveX个样本。

此外,对于控件实现的所有自定义接口和事件接口,您缺少HKCR \ Interfaces下的条目。

答案 3 :(得分:3)

这不是详尽无遗的,但请尝试this MS知识库文章。

另外,Larry Osterman有一篇有用的博文here


我发现另一种方法是使用像RegMon这样的工具,并直接监视调用DllRegisterServer方法时所做的注册表更改。

答案 4 :(得分:0)

无论如何,请与拉里·奥斯特曼的文章联系起来。

此外,一个很好的起点是由MSVC ATL COM对象向导生成的ATL注册器脚本。您可以使用不同的选项,看看它们如何影响输出。

答案 5 :(得分:0)

旁注如果您想通过实验查看创建了哪些密钥:使用Sysinternals'Process Monitor,它会在您注册控件时实时捕获注册表上的活动。

答案 6 :(得分:-1)

你在使用64位操作系统吗?

如果是这样,而不是写入 HKEY_CLASSES_ROOT \ CLSID \
你应该写信给 HKEY_CLASSES_ROOT \ Wow6432Node \ CLSID \