注册表和COM

HKEY_CLASSES_ROOT 是 Windows 注册表中的一个关键部分,它存储与文件关联和 COM 类相关的信息。具体来说,它包含以下内容:
文件扩展名关联:定义文件扩展名与应用程序之间的关联,决定了双击某种文件类型时调用哪个应用程序。
CLSID:存储 COM 类的类标识符(CLSID),用于注册和定位 COM 组件。
ProgID:程序标识符,用于标识 COM 类的可读名称。
接口和类型库:定义 COM 接口和类型库的信息。
HKEY_CLASSES_ROOT 实际上是 HKEY_LOCAL_MACHINE\Software\Classes 和 HKEY_CURRENT_USER\Software\Classes 的合并视图。用户特定的设置优先于全局设置。


在 Windows 注册表中,HKEY_CLASSES_ROOT 是 HKEY_LOCAL_MACHINE\Software\Classes 和 HKEY_CURRENT_USER\Software\Classes 的合并视图。合并规则如下:
优先级:HKEY_CURRENT_USER\Software\Classes 中的设置优先于 HKEY_LOCAL_MACHINE\Software\Classes。这意味着如果同一个键在两者中都存在,系统会使用 HKEY_CURRENT_USER 中的值。
合并显示:如果某个键只存在于 HKEY_LOCAL_MACHINE 或 HKEY_CURRENT_USER 中,它将直接显示在 HKEY_CLASSES_ROOT 中。
用户特定覆盖全局:用户特定的设置可以覆盖全局设置,以允许用户自定义或覆盖系统默认行为。
这种合并机制允许用户在不影响其他用户或系统全局设置的情况下,自定义COM组件和文件关联等配置。


当你想修改注册表中的数值时,应该根据具体需求选择修改的位置:
修改 HKEY_CURRENT_USER\Software\Classes:
如果你想为当前用户设置特定的配置或覆盖全局设置,修改这里。
适用于用户特定的自定义设置,不会影响其他用户。
修改 HKEY_LOCAL_MACHINE\Software\Classes:

如果你希望更改全局设置,适用于所有用户,修改这里。
需要管理员权限,因为这会影响整个系统。
不要直接修改 HKEY_CLASSES_ROOT:

虽然可以在 HKEY_CLASSES_ROOT 下直接修改,但这实际上会影响 HKEY_CURRENT_USER 或 HKEY_LOCAL_MACHINE 中的相应键。
为了清晰和避免混淆,建议直接在 HKEY_CURRENT_USER 或 HKEY_LOCAL_MACHINE 中修改。
选择修改的位置时,请确保理解更改的影响范围,以免意外影响系统或其他用户的设置。

 

 

InprocServer32 键值用于指定一个 COM 组件的本地服务器DLL文件路径。它定义了当 COM 组件在进程内(In-process)运行时,系统应该加载哪个DLL文件。具体来说:
In-process Server:指的是组件作为调用应用程序的一个动态链接库(DLL)运行,而不是一个独立的进程。这通常可以提高性能,因为它减少了进程间通信的开销。
InprocServer32:键值下存储的路径指向实现该COM对象的DLL文件。当一个应用程序请求该COM对象时,系统会加载这个DLL并在调用应用程序的进程内运行它。
这个设置通常位于注册表路径 HKEY_CLASSES_ROOT\CLSID\{Your-CLSID}\InprocServer32 下,其中 {Your-CLSID} 是具体COM组件的类标识符。


InprocServer32下
Version
表示组件版本:它记录了该 COM 组件或 DLL 文件的具体版本号,用于标识该组件的特定版本。这有助于系统和应用程序在运行时确定使用的是正确的组件版本,避免版本不兼容的问题。
方便版本管理:对于软件开发者和系统管理员来说,通过查看Version值,可以方便地了解系统中安装的 COM 组件的版本情况,以便进行版本升级、兼容性检查等操作。

ThreadingModel
指定线程模型:它定义了 COM 组件在多线程环境中的行为方式,即该组件如何处理并发访问和线程同步。常见的线程模型有Apartment(单元)、Free(自由)、Both(两者)等。不同的线程模型适用于不同的应用场景,正确设置线程模型可以确保组件在多线程环境中的正确运行,避免线程安全问题。
影响性能和资源利用:线程模型的选择会影响 COM 组件的性能和资源利用效率。例如,Apartment线程模型在单线程单元中运行组件,具有较好的线程安全性,但可能会限制并行性;而Free线程模型允许组件在多个线程中自由运行,具有更高的并行性,但需要开发者自行处理线程同步问题。

在 COM(Component Object Model)组件对象模型中,线程模型规定了组件在多线程环境中的行为方式,以下是 Apartment(单元)、Free(自由)、Both(两者)线程模型的结构及区别:
Apartment(单元)线程模型
结构特点
单线程单元:基于 STA(Single-Threaded Apartment)模式,每个 COM 对象都与一个特定的线程相关联,这个线程被称为该对象的 “单元”。对象在其所属的单元线程中执行所有的方法调用,同一时刻只有一个线程可以访问该对象。
消息循环:通常在单元线程中会有一个消息循环,用于处理来自外部的方法调用请求。当其他线程需要调用该对象的方法时,调用会被封送到对象所在的单元线程中进行处理。
适用场景
线程安全要求高:对于那些不是线程安全的 COM 组件,或者在多线程环境中需要严格控制并发访问的组件,Apartment 线程模型是一个很好的选择。它可以确保组件在任何时候都只被一个线程访问,避免了多线程并发访问可能导致的数据不一致或状态混乱问题。
UI 交互组件:在与用户界面相关的 COM 组件中,如 ActiveX 控件,通常使用 Apartment 线程模型。因为 UI 组件通常不是线程安全的,需要在一个特定的线程中进行更新和交互,以确保界面的正确显示和响应。
Free(自由)线程模型
结构特点
多线程访问:采用 MTA(Multithreaded Apartment)模式,COM 对象可以被多个线程同时访问,组件本身需要负责处理线程同步和并发控制。这意味着组件开发者需要在代码中使用适当的同步机制,如互斥锁、信号量等,来确保在多线程环境中的数据一致性和线程安全。
无固定线程关联:与 Apartment 线程模型不同,Free 线程模型中的 COM 对象不与任何特定的线程绑定,任何线程都可以直接调用对象的方法,而不需要封送调用到特定的线程。
适用场景
高性能需求:在对性能要求较高的场景中,如服务器端的 COM 组件,Free 线程模型可以充分利用多线程的并行性,提高组件的响应速度和处理能力。多个客户端线程可以同时调用组件的方法,而不需要等待其他线程的操作完成。
线程安全组件:对于本身就是线程安全的 COM 组件,或者组件开发者已经在内部实现了完善的线程同步机制的组件,Free 线程模型可以提供更好的性能和灵活性,允许组件在多线程环境中自由运行。
Both(两者)线程模型
结构特点
兼具两种模式:这种线程模型的 COM 组件既可以在 Apartment 线程模型下工作,也可以在 Free 线程模型下工作。它在实现上通常会根据组件的使用环境和调用方式自动切换线程模型。
灵活适配:当组件在 Apartment 环境中被调用时,它会像 Apartment 线程模型那样工作,与一个特定的线程关联,并通过消息循环处理调用请求;当组件在 Free 环境中被调用时,它会像 Free 线程模型那样允许多线程并发访问,并自行处理线程同步问题。
适用场景
兼容性需求高:在一些复杂的 COM 组件开发中,为了满足不同客户端的需求,组件可能需要同时支持 Apartment 和 Free 线程模型。例如,一些既有可能在单线程的客户端应用中使用,又有可能在多线程的服务器端应用中使用的组件,可以采用 Both 线程模型,以提供更好的兼容性和灵活性。
组件库开发:对于一些通用的 COM 组件库,为了方便不同类型的开发者使用,可能会采用 Both 线程模型。这样,组件库可以在各种不同的线程环境中正常工作,而不需要开发者为不同的线程模型单独开发不同的版本。


在 COM 组件相关的注册表设置中,ImplementedInThisVersion字段通常用于标识该 COM 组件在当前系统环境下是否已针对特定版本实现或启用了某些特定功能或特性,以下是详细介绍:
功能特性方面
特定功能的标识:用于指示 COM 组件在当前版本中所实现的具体功能集或特性集合。例如,一个 COM 组件可能在不同版本中有不同的功能扩展或优化,ImplementedInThisVersion字段可以明确表示当前版本中哪些功能是有效的、已实现的。
功能兼容性指示:帮助应用程序或其他组件了解该 COM 组件在当前系统版本中的功能兼容性情况。如果该字段的值与应用程序所期望的功能版本不匹配,可能会导致一些功能无法正常使用或出现兼容性问题。
版本管理方面
组件版本关联:将 COM 组件的实现与特定的版本号相关联。当系统中存在多个版本的 COM 组件或同一组件的不同版本在不同环境中使用时,通过该字段可以快速确定当前正在使用的组件版本及其对应的实现情况。
版本更新标识:在组件进行版本更新时,该字段可以作为一个标识,用于区分不同版本之间的实现差异。开发人员可以根据该字段的值来判断是否需要对应用程序进行相应的调整或更新,以适配 COM 组件的新实现。
运行环境方面
系统环境适配:表示 COM 组件在当前系统环境下的实现状态。不同的操作系统版本、系统配置或运行时环境可能会对 COM 组件的运行产生影响,ImplementedInThisVersion字段可以用于指示该组件是否已针对当前系统环境进行了优化或适配。
依赖关系标识:可能用于标识 COM 组件在当前版本中对其他组件或库的依赖关系。如果该组件依赖于特定版本的其他组件或库才能正常运行,ImplementedInThisVersion字段可以提供相关的信息,以便在部署或运行时进行正确的配置和管理。


ProgID 即编程标识符(Programmatic Identifier),是 COM 组件在注册表中的唯一字符串标识符。以下是具体介绍:
标识与关联
唯一标识 COM 对象:由组件供应商定义,用于在注册表中标识 COM 对象,在 COM 编程中作为创建 COM 对象实例的一种便捷方式,让开发人员更方便地引用和操作 COM 组件。
关联 CLSID:与 CLSID(Class Identifier,类标识符)紧密关联,CLSID 是一个 128 位的全局唯一标识符,用于唯一标识 COM 组件类。ProgID 提供了一种更友好的、可读性更强的字符串表示形式,方便开发人员使用。
格式与规范
格式要求:通常采用<program>.<component>.<version>的格式,由点号分隔,且不包含空格,例如Word.Document.6。
规范限制:ProgID 的长度不能超过 39 个字符,除了点号外不能包含其他标点符号,不能以数字开头,并且要与任何 OLE1 应用程序的类名不同。
作用与用途
编程调用:在编程中,当无法使用 CLSID 时,可以使用 ProgID 来创建 COM 对象的实例。例如,在 Visual Basic、VBA、PowerShell 等编程语言中,可以通过指定 ProgID 来实例化 COM 对象。
兼容性与版本管理:用于表示 COM 对象之间的二进制代码兼容性。不同版本的 COM 组件可能具有不同的 ProgID,通过 ProgID 可以方便地识别和使用特定版本的组件,有助于实现组件的版本管理和兼容性控制。


COM 组件中Server字段具有丰富含义,以下是具体介绍:
组件位置与加载信息
进程内组件:对于以 DLL 形式存在的进程内组件,Server字段通常指定该 DLL 文件的完整路径。例如,C:\Windows\System32\oleaut32.dll,系统通过此路径找到并加载该 DLL 到调用进程的地址空间,使组件在进程内执行。
进程外组件:如果是 EXE 形式的进程外组件,Server字段包含 EXE 文件的路径以及可能的启动参数等。如C:\Program Files\Common Files\System\ado\msado15.dll,系统会根据这些信息启动对应的进程外组件服务器程序,客户端再通过进程间通信机制与之交互。
组件运行环境标识
远程服务器指定:在分布式 COM(DCOM)应用中,Server字段用于明确组件所在的远程服务器的名称或网络地址等信息。比如\\ServerName\Share\MyComponent.exe,客户端可借此通过网络连接到指定远程服务器上的组件进行调用。
服务器类型说明:标识组件所运行的服务器类型或环境,如 COM + 应用服务器、IIS 服务器等。不同服务器类型有不同特性和配置要求,通过该字段系统和客户端能了解组件运行环境。例如,在 COM + 环境中,组件的Server字段可能指向 COM + 应用服务器的特定应用程序代理。
组件加载与管理细节
加载方式指示:包含组件加载方式的相关指示信息,如是否延迟加载、是否以共享模式加载等。延迟加载可提高系统启动速度,在组件首次被调用时才加载;共享模式则允许多个客户端共享同一个组件实例,提高资源利用率。
资源管理信息:在复杂 COM 组件系统中,Server字段可能包含与资源管理相关的信息,如组件所使用的数据库连接字符串、消息队列名称等。以数据库连接组件为例,Server字段可能包含连接数据库的相关配置信息,如Server=localhost;Database=MyDB;User ID=sa;Password=123456 ,组件在运行时据此正确获取和管理所需资源。


在 COM 组件中,TypeLib 即类型库(Type Library),具有以下含义:
元数据存储
接口与类的描述:以二进制格式存储 COM 组件中接口、类、方法、属性等的定义和相关元数据信息,是对 COM 组件的一种结构化描述。
规范与统一:提供了一种统一规范的方式来描述 COM 组件的类型信息,使得不同编程语言和开发环境能够理解和使用 COM 组件,促进了 COM 组件在不同应用程序之间的交互和共享。
运行时支持
动态获取信息:在运行时,通过 TypeLib,程序可以动态获取 COM 组件的接口和类的信息,如接口的方法签名、属性类型等,从而实现动态调用 COM 组件的功能。
跨语言调用:支持不同编程语言对 COM 组件的调用,不同语言的编译器或开发环境可以根据 TypeLib 中的信息,将 COM 组件的接口和类转换为相应语言的本地类型,方便开发人员在各自熟悉的编程语言中使用 COM 组件。
开发辅助
代码生成:开发工具可以根据 TypeLib 中的信息自动生成代码,如在 Visual Studio 中,添加对 TypeLib 的引用后,会自动生成对应的互操作程序集(interop assembly),其中包含了与 COM 组件的接口和类对应的托管代码定义,减少了开发人员手动编写代码的工作量。
自动完成与提示:在集成开发环境(IDE)中,当加载了 TypeLib 后,IDE 可以根据其中的信息提供自动完成和代码提示功能,方便开发人员编写调用 COM 组件的代码,提高开发效率。
版本管理
多版本支持:可以包含同一 COM 组件的多个版本的类型信息,方便在不同版本的 COM 组件之间进行切换和管理,同时也有助于解决组件版本兼容性问题。
向后兼容:通过 TypeLib,COM 组件的开发者可以在不破坏现有接口和类的兼容性的前提下,对组件进行升级和改进,保证了使用该组件的旧版本应用程序仍然能够正常运行。


不使用注册表调用COM

是的,COM 组件可以在不注册的情况下使用,但需要采取一些不同的方法。通常,COM 组件需要在系统中注册,以便其他应用程序通过其 CLSID 或 ProgID 来识别和使用它。但如果不想注册组件,可以使用以下方法:
使用 DLL 的完整路径:
在应用程序中直接加载 COM DLL 文件,使用 CoCreateInstance 或类似函数时提供组件的完整路径。
注册表重定向:
在应用程序启动时,临时设置注册表环境(例如,使用注册表重定向技术)来指向未注册的 COM 组件。
Embedding COM 组件:
在应用程序中嵌入 COM 组件的相关信息,直接通过代码调用接口,而不依赖注册表。
使用 RegFree COM(注册表无关 COM):
通过在应用程序的清单文件中指定 COM 组件的信息,实现不注册也能使用 COM 组件的功能。
这些方法可以帮助你在不修改系统注册表的情况下使用 COM 组件,但实现起来可能会比较复杂,需要对 COM 和 Windows 编程有深入的了解。

 

即使注册表中没有直接找到特定的 CLSID,.NET 仍然可以正常调用这些 COM 组件,可能有以下几个原因:
系统自带组件:某些 COM 组件是 Windows 系统自带的,可能通过其他方式注册或内置在系统中。
版本变化:不同版本的 Windows 或 Internet Explorer 可能使用不同的 CLSID 或通过其他机制来实现相同的功能。
封装和抽象:.NET 提供了对这些组件的高级封装,使开发者无需直接处理底层的 COM 细节。
兼容性:Windows 系统可能有兼容层或重定向机制,确保常用组件的正常工作,即使某些注册表项缺失。
因此,尽管注册表中可能没有直接的 CLSID,.NET 仍能通过其他机制调用这些组件。

 

posted @   卖雨伞的小男孩  阅读(63)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2017-12-18 设计模式のStrategyPattern(策略模式)----行为模式
点击右上角即可分享
微信分享提示