COM ID 和注册表项概览






4.87/5 (36投票s)
2001年7月25日
11分钟阅读

238458
关于 COM ID 和注册表的文章
小节:
一些 COM 定义 
COM 接口
当我们谈论接口时,我们也在谈论接口定义与实现之间的分离。因此,接口定义了实现者和使用者之间的契约,从物理上阻止使用者访问任何实现细节。你可以将接口看作一组方法。这组方法为你提供服务。只要你能使用所需的服务,你就不必关心这些方法的实现。COM 接口指的是 COM 类实现的一组预定义的、相关联的函数,但它不一定代表该 COM 类支持的所有函数。
一位面向对象编程(OOP)学者说,我们应该专注于对象的外部视图,他称之为契约式编程(B. Meyer, Object-Oriented Software Construction, 1988)。
COM 使用了契约式编程的概念。
COM 世界的规则之一是,所有 COM 接口都必须直接或间接地派生自 IUnknown 接口。
COM 类
或
组件对象类 (coclass)
(摘自 Platform SDK: COM / COM Class Objects and CLSIDs)“COM 服务器是以 COM 类的形式实现的。COM 类是在你与给定对象交互时执行的一组接口的代码实现。
C++ 类和 COM 类之间有一个重要的区别。在 C++ 中,类是一种类型。而 COM 类仅仅是对象的定义,不带有类型,尽管 C++ 程序员可能会使用 C++ 类来实现它。COM 的设计允许一个类被不同的应用程序使用,包括那些在编写时并不知道该特定类存在的应用程序。因此,给定类型对象的类代码存在于动态链接库(DLL)或另一个应用程序(EXE)中。”
COM 对象
COM 对象是 COM 类在运行时的实例。COM 类对象
或
类工厂
(摘自 Platform SDK: COM / COM Class Objects and CLSIDs)“创建类(COM 类)实例的基本方法是通过 COM 类对象。这只是一个中间对象,支持创建给定类(COM 类)的新实例(COM 对象)所共有的函数。大多数用于从 CLSID 创建对象的类对象都支持 IClassFactory 接口,该接口包含一个重要的方法 CreateInstance。你需要为你提供的每个可实例化的(COM)对象类实现一个 IClassFactory 接口。
支持某些其他自定义类工厂接口的服务器不要求一定支持 IClassFactory。但是,调用除 CoGetClassObject 之外的激活函数(例如 CoCreateInstanceEx)则要求服务器支持 IClassFactory。”
Platform SDK: Automation 将类工厂称为“一个实现了 IClassFactory 接口的对象,它允许创建特定类的其他对象。”。我只想补充一点,它也可能是其他的类工厂接口(不仅仅是 IClassFactory 接口),例如 IClassFactory2 或自定义接口。
COM 组件
COM 组件指的是一个二进制模块,例如 DLL 或可执行文件。注册后,一个组件将公开一个或多个 COM 类对象(或对象工厂)。类型库
类型库包含一个或多个 COM 元素的规范(元数据),包括类、接口、枚举等。这些文件以标准的二进制格式存储。类型库可以是一个扩展名为 .tlb 的独立文件,也可以作为资源存储在可执行文件中,其文件扩展名可以是 .ocx、.dll 或 .exe。COM ID 
在 COM 的世界里,你必须标识不同的部分,如 coclass、接口、类型库、应用程序等。这些部分必须在全世界是唯一的。COM 使用全局唯一标识符(Globally Unique IDentifier,GUID)来定义这些不同的 ID。
在接口定义语言(IDL)文件中,你必须使用属性 uuid,它代表通用唯一标识符(Universally Unique IDentifier)。UUID 和 GUID 是等效的。
那么,什么是 GUID 呢?GUID 是一个 128 位的数字,通常用十六进制表示,它保证“在空间和时间上都是唯一的”。例如,下面的数字就是一个 GUID:
{60B4140E-B0A7-4540-B744-7E1A944E8C78}
COM 从分布式计算环境(DCE)的命名方案中借鉴了这套标识系统。DCE RPC 系统使用 UUID。主要的 COM ID 有:
- LIBID:类型库 ID,基于 GUID。
- APPID:应用程序 ID,基于 GUID。
- CLSID:COM 类 ID,基于 GUID。
- IID:接口 ID,基于 GUID。
- PROGID:程序 ID,基于一个文本字符串。

注意:此图表并不完整,例如缺少了类工厂。
要获取 GUID/UUID,你可以使用:
- COM 工具包(或“\Microsoft Visual Studio\Common\Tools”)的 \TOOLs 目录下的 UUIDGEN.EXE。
- “\Microsoft Visual Studio\Common\Tools” 目录下的 GUIDGEN.EXE。
- COM API 函数 CoCreateGuid()。
注册表 
在开始之前,这里是 Windows 注册表文档中使用的一些缩写及其含义:- HKLM:HKEY_LOCAL_MACHINE 键。在此键下注册的信息可能适用于本地计算机上的所有用户。
- HKCR:HKEY_CLASSES_ROOT 键,是 HKEY_LOCAL_MACHINE\Software\Classes 的一个快捷方式。
- HKCU:HKEY_CURRENT_USER 键。
COM 从本地注册表中检索有关 COM 类的信息。在 Windows 2000 中,现在有了一个名为 Active Directory 的全局实现存储库。COM 也使用注册表来查找接口属性和安全相关的配置,以便管理封送和分布式访问。
本地工作站上所有与 COM 类相关的配置信息都存储在以下注册表项中:
- HKEY_CLASSES_ROOT,为了向后兼容。
- HKEY_LOCAL_MACHINE\Software\Classes,在 Windows NT 4.0 上可用。
- HKEY_CURRENT_USER\Software\Classes,在 Windows 2000 上可用。
HKEY_CLASSES_ROOT\CLSID\{GUID}
或
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{GUID} 或 (仅限 Windows 2000)
HKEY_CURRENT_USER\SOFTWARE\Classes\CLSID\{GUID} 
CLSID 是一个全局唯一标识符,用于标识一个 COM 类对象。AppID 节点 | |
|
|
![]() |
|
|
|
![]() |
|
|
|
![]() |
CLSID_value 是一个 128 位的全局唯一标识符(GUID),用于标识 CLSID 键。 |
![]() |
字符串值 人类可读的名称。 |
![]() |
字符串值 它是一个 128 位的全局唯一标识符(GUID),用于标识 AppID 键。 |
![]() |
自动对象类转换 |
![]() |
字符串值 给定对象或对象类应转换到的对象的类标识符(CLSID)。 |
![]() |
分配 TreatAs 值 |
![]() |
字符串值 将自动分配给 TreatAs 条目的 CLSID。 |
![]() |
将对象标识为控件 |
![]() |
ShortDisplayName |
![]() |
字符串值 指定应用程序的短显示名称,用于菜单,包括弹出菜单(例如,“Chart”)。 |
![]() |
应用程序名称 |
![]() |
字符串值 指定应用程序名称,用于“选择性粘贴”对话框的结果字段中(例如,“Super Graph 2001 Chart”)。 |
![]() |
将对象标识为 ActiveX 控件 |
![]() |
字符串值 此可选条目由容器用于填充对话框。容器使用此子项来确定是否在显示 ActiveX 控件的对话框中包含某个对象。 |
![]() |
“转换”对话框使用的转换 |
![]() |
|
![]() |
|
![]() |
字符串值 应用程序可以读取(转换自)的文件格式。 |
![]() |
|
![]() |
|
![]() |
字符串值 应用程序可以读写(激活为)的文件格式。 |
![]() |
应用程序支持的格式 |
![]() |
提供默认图标信息 |
![]() |
字符串值 指定对象应用程序可执行文件的完整路径以及可执行文件中图标的资源索引(例如,“c:\toto\titi.exe,0”)。 |
![]() |
注册一个 16 位处理程序 DLL |
![]() |
字符串值 指定应用程序使用的自定义处理程序。 |
![]() |
注册一个 32 位处理程序 DLL |
![]() |
字符串值 指定应用程序使用的自定义处理程序。 |
![]() |
注册一个 16 位进程内服务器 DLL |
![]() |
字符串值 指定进程内服务器 DLL 的路径。 |
![]() |
注册一个 32 位进程内服务器 DLL |
![]() |
字符串值 指定 32 位进程内服务器的路径。 |
![]() |
字符串值 指定服务器可以在其中运行的单元的线程模型。 进程内服务器被加载到现有单元中,因此不调用 CoInitialize 或 CoInitializeEx;它们必须使用注册表来指定应用程序的线程模型。 允许的值为: ThreadingModel=Apartment。单线程单元。 ThreadingModel=Both。单线程或多线程单元。 ThreadingModel=Free。多线程单元。 ThreadingModel=Neutral。中立单元(在 Windows 2000 中可用)。 |
![]() |
指示对象是否可在 COM 应用程序中插入。 当 COM 容器应用程序使用时,此类的对象应出现在“插入对象”对话框的列表框中。 |
![]() |
字符串值 指定 32 位进程内服务器的路径。 |
![]() |
16 位本地服务器应用程序的完整路径 |
![]() |
字符串值 指定本地服务器的完整路径,可以包含命令行参数。 |
![]() |
32 位本地服务器应用程序的完整路径 |
![]() |
字符串值 指定本地服务器的完整路径,可以包含命令行参数。 |
![]() |
指定如何创建和显示对象 |
![]() |
类的编程标识符 |
![]() |
字符串值 将 ProgID 与 CLSID 关联。通常,ProgID 的结构类似于:<供应商>.<组件>.<版本> 并且必须:
|
![]() |
标识用于工具栏或工具箱按钮面的 16x16 位图的模块名称和资源 ID |
![]() |
字符串值 指定位图的模块名称和资源 ID(例如,“c:\toto\titi.dll,5”)。 |
![]() |
指定可以模拟当前类的类的 CLSID |
![]() |
字符串值 将要执行模拟的类的 CLSID。 模拟是一个应用程序打开和编辑不同类的对象,同时保留对象原始格式的能力。 |
![]() |
与应用程序关联的动词 |
![]() |
控件的版本号 |
![]() |
字符串值 控件的版本号。 版本号应与与控件关联的类型库的版本相匹配。. |
HKEY_CLASSES_ROOT\AppID\{GUID}
或
HKEY_LOCAL_MACHINE\Software\Classes\AppID\{GUID} 
AppID 注册表项将 COM 服务器公开的所有 coclass 的配置和安全选项分组,它在注册表中的位置如下:AppID 节点 | |
|
|
![]() |
|
|
|
![]() |
|
|
|
![]() |
AppID_value 是一个 128 位的全局唯一标识符(GUID),用于标识 AppID 键。 |
![]() |
字符串值 通常是组件的人类可读名称。 |
![]() |
二进制值 设置一个 ACL 来决定访问权限。 |
![]() |
字符串值 将客户端配置为在与持久性存储相同的系统上激活。任何以 Y 或 y 开头的值都表示应使用 ActivageAtStorage。 |
![]() |
DWORD 值 设置默认身份验证。值为 1 到 6,对应于 RPC_C_AUTHN_LEVEL_xxx 常量。 请注意,名为 AuthenticationLevel 的值仅在 Windows NT 4.0 SP4 和 Windows 2000 以及 dcom95 1.1 上受支持。 . |
![]() |
字符串值 命名用于远程或本地加载 DLL 的代理进程。要使用系统提供的通用代理进程,请将 surrogate_path 设置为空字符串或 NULL。 |
![]() |
二进制值 设置 ACL,决定谁可以启动该应用程序。 |
![]() |
字符串值 将组件配置为作为 Win32 服务运行。 对于本地和远程激活请求,优先使用名为 LocalService 的值而不是 LocalServer32 键——如果 LocalService 存在并指向一个有效的服务,则忽略 LocalServer32 键。 |
![]() |
字符串值 将组件配置为作为 Win32 服务运行。 |
![]() |
字符串值 远程服务器的名称。 |
![]() |
字符串值 设置一个应用程序仅以给定用户身份运行。其形式必须是 username、domain\username 或字符串 "Interactive User"。要为 RunAs 类设置密码,必须使用安装在系统目录中的 DCOMCNFG 管理工具。 |
![]() |
字符串值 设置在调用时传递给 LocalService 的参数。 |
引用 ACL 值的键(AccessPermission 和 LaunchPermission)必须使用适当的工具(如 DCOMCNFG.EXE)进行设置。
HKEY_CLASSES_ROOT\Interface\{GUID}
或
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Interface\{GUID} 
Interface 注册表项通过将接口名称与接口 ID(IID)关联来注册新接口,它在注册表中的位置如下:AppID 节点 | |
|
|
![]() |
|
|
|
![]() |
|
|
|
![]() |
IID_value 是一个 128 位的全局唯一标识符(GUID),用于标识该接口。 |
![]() |
字符串值 通常是接口的人类可读名称。 |
![]() |
派生自的接口 |
![]() |
字符串值 派生自的接口的 IID (GUID)。 |
![]() |
方法数量 |
![]() |
字符串值 接口公开的方法数量。 |
![]() |
将 IID 映射到 CLSID(16 位 DLL) |
![]() |
字符串值 指定要将 IID 映射到的 CLSID (GUID)。 如果添加接口,则必须使用此条目来注册它们(16 位系统),以便 OLE 能够找到适当的远程处理代码来建立进程间通信。 |
![]() |
将 IID 映射到 CLSID(32 位 DLL) |
![]() |
字符串值 指定要将 IID 映射到的 CLSID (GUID)。 这是一个必需的条目,因为 16 位和 32 位接口的 IID 到 CLSID 的映射可能不同。IID 到 CLSID 的映射取决于接口代理被打包到一组代理 DLL 中的方式。 如果添加接口,则必须使用此条目来注册它们(32 位系统),以便 OLE 能够找到适当的远程处理代码来建立进程间通信。 |