COM / ActiveX / OCX 是什么 - 区别与关系整理

· · COM, ActiveX, OCX, OLE, Windows 开发, 遗留技术

COM/ActiveX/OCX 这 3 个词,在 Windows 的遗留(legacy)项目里几乎都会成套出现。

  • 厂商发来一个 .ocx
  • Access 或 VB6 界面上放着奇怪的控件
  • 别人刚说完“这是 COM”,转眼又说“是 ActiveX 啦”
  • 紧接着 regsvr32、32bit/64bit、IE 模式等字眼一起涌上来

这条流程走下来,基本上对话就会突然变得混乱。

原因是这些词彼此相近,历史上也大量重叠。 但在实务上,只要能把这几个概念分清楚,排查、迁移、解释的难度都会明显下降。

本文会按照“区别与关系看得出来的顺序”来整理“什么是 COM”“什么是 ActiveX”“什么是 OCX”。 特别会厘清 哪个是底层、哪个是组件、哪个是文件

1. 先下结论(一句话)

先给一个粗略但好用的说法:

  • COM 是底层。它是 Windows 上组件之间互操作的二进制契约
  • ActiveX 是基于 COM 的组件语境,尤其常指“可嵌入宿主使用的控件”
  • OCX 是 ActiveX 控件实现常见的文件,以扩展名形式出现
  • 也就是说 COM = 机制、ActiveX = 组件的语境、OCX = 文件,这样记会好整理得多
  • “ActiveX = 老 IE 上危险的那个东西”这个印象,只对了一半。ActiveX 并非浏览器专用
  • “OCX = ActiveX”在口语里几乎被当作同义词,但严格来说是把概念与扩展名混在了一起
  • 现在新开发时不会拿它当主角,但在既有 Windows 应用、Office、Access、设备 SDK、内部 Web 中还会遇到

简单说,先把下面 3 件事分开来看:

  1. 这是 COM 的话题
  2. 这是 ActiveX 控件的话题
  3. 还是只是 看到 .ocx 文件就这么叫

把这 3 件事分清楚,迷雾会消散很多。

2. 本文所说的 COM / ActiveX / OCX

实务中这三个词常常被混用,所以先固定一下本文的用法:

  • COM:Windows 的组件模型本身。接口、GUID、注册、调用的底层
  • ActiveX:以 COM 为基础的可嵌入控件或其使用语境。实务上常指 ActiveX 控件
  • OCX:ActiveX 控件实现常见的扩展名,.ocx

补充一下,历史上“ActiveX”这个词曾用得更宽泛。 但现在实务上遇到“ActiveX”让人头疼的地方,多半落在 控件、嵌入、宿主、浏览器、注册 这一带。

所以本文基本上把 ActiveX 当作 ActiveX 控件的同义词 来处理。

3. 先用一张图收拢

3.1. 关系图

先用一张图看全貌比较快:

flowchart LR
    COM["COM<br/>二进制契约的底层"] --> OLE["OLE / Automation<br/>嵌入、自动化的机制"]
    OLE --> AX["ActiveX<br/>以 COM 为基础的控件语境"]
    AX --> CTRL["ActiveX 控件"]
    CTRL --> OCX["OCX (.ocx)<br/>常见的实现文件形式"]

    HOST["宿主/容器<br/>IE / Access / VB6 / MFC / WinForms"] --> CTRL

这张图的重点是:COM 与 ActiveX 不是同一个词

  • COM 是底层
  • OLE/Automation 是嵌入与自动化的机制
  • ActiveX 是在其之上的控件语境
  • OCX 是控件实现常见的文件

所以当别人问“ActiveX 是不是就是 COM”,答案是 底层是 COM,但 ActiveX 并不等于 COM

3.2. 最简名词整理

第一印象
COM 机制、契约、底层
ActiveX 以 COM 为基础的嵌入式组件语境
ActiveX 控件 真正放到宿主上的组件本身
OCX ActiveX 控件常见的扩展名
OLE/Automation 嵌入、自动化、集成的机制

最简记法:

  • COM 是机制
  • ActiveX 是组件的语境
  • OCX 是文件

4. 什么是 COM

4.1. 一句话说

COM 是 Component Object Model 的缩写,是 Windows 上组件之间互操作的 二进制契约

这里说的二进制契约,指的不是源代码或语言规范上的约定,而是 在编译后的层级也能维持的接口约定。 用 C++ 写的组件能被其他语言或其他应用使用,就是因为这个契约。

用实务的感受来说,COM 与其说是“一种方便的库发布方式”,不如说是 把实现隐藏起来,只靠契约对接的机制

典型的 COM 元素例如:

  • IUnknown 管理引用计数
  • QueryInterface 查找接口
  • IIDCLSID 这类 GUID 做标识
  • 以 DLL 形式做进程内(in-proc)使用
  • 以 EXE 形式做跨进程(out-of-proc)使用

简言之,COM 是 Windows 组件化文化的底层

4.2. COM 的核心要点

只看基本要点,COM 的核心是:

  • 以接口为中心
    • 先决定要公开什么,再谈实现
  • 以 GUID 标识
    • 类与接口都有唯一标识符
  • 宿主与实现分离
    • 调用方不必知道内部实现
  • 能跨进程
    • 不仅同一进程内,跨进程也能当作组件使用

这些正是 COM 不只是“老古董”的原因。 它在相当早期就已经把 以契约为基础的复用 这件事做得足够扎实。

5. 什么是 ActiveX

5.1. 一句话说

ActiveX 可以理解为:以 COM 为基础的 可复用软件组件,尤其是 嵌入到宿主或容器中使用的控件

实务上提到“ActiveX”,多半指的就是 ActiveX 控件。 例子有按钮、表格、图表、日历、查看器、设备连接组件等。

所以 ActiveX 不是“一个独立、高大上的庞大技术”,而是 在某个宿主中嵌入、运行的组件。这样理解不容易跑偏。

5.2. ActiveX 并非浏览器专用

“ActiveX = Internet Explorer 那个东西”的印象相当强烈。这句话不算错,但 仅仅这样理解不够

ActiveX 控件也被用在:

  • Access 表单
  • VB6 应用
  • MFC 的容器
  • Office / VBA 周边
  • 从 WinForms 通过 COM 包装器使用
  • IE 或兼容运维场景

也就是说,ActiveX 是 Windows 应用本身长期使用的嵌入式组件技术,并非只用在浏览器。

不理解这一点,就会把内部 Web 上的 ActiveX 与 Access 界面里的 ActiveX 看成两件事。 实际上这两者都相当接近 COM 家族。

6. 什么是 OCX

6.1. 一句话说

OCX 是 ActiveX 控件实现常用的扩展名。 在 Windows 现场看到 .ocx,很大概率是 嵌入式控件类的 COM 组件

常见场景:

  • 厂商 SDK 的发布物
  • VB6/Access/MFC 的老项目
  • 安装程序里会被注册的文件
  • 需要 regsvr32 的组件

这里的重点是:OCX 是文件形式,不是概念本身。 所以如果要简单回答“OCX 是什么”,答案就是 实务上遇到 ActiveX 控件实体时,非常常见的一种文件

6.2. 和 .dll 有什么不同

这也是容易混淆的地方:

  • .ocx 相当明确地暗示着“这是 ActiveX 控件”
  • .dll 可能是普通库、COM server,也可能是 ActiveX 周边的依赖 DLL

所以看到 .ocx 基本可以判断是 ActiveX 那一路,但光看到 .dll 还判断不出是什么。

实务上常见的组合:

  • vendorcontrol.ocx
  • vendorhelper.dll
  • vendorcore.dll

主角是 OCX,DLL 在旁边辅助。

所以如果被问“OCX 是不是 DLL 的一种”,感觉上算接近,但在排查场景中建议 把角色分开看

7. 区别整理成表

身份 实务常见相关词 常见实体
COM 组件模型、二进制契约底层 IUnknownQueryInterfaceCLSIDIID、Apartment .dll.exe、注册表信息
ActiveX 以 COM 为基础的控件语境 容器、嵌入、property、事件 ActiveX 控件
ActiveX 控件 实际被放到宿主的可复用组件 表格、日历、查看器、设备连接 .ocx.dll
OCX ActiveX 控件常见的扩展名 regsvr32、工具箱、32bit/64bit xxx.ocx
OLE/Automation 嵌入与自动化的机制 Office 集成、属性页、automation 各种以 COM 为基础的功能

用这张表记忆的话就是:

  • COM 是地基
  • ActiveX 是建在地基上的组件文化
  • OCX 是现场会捡到的文件

8. 实际被用在哪里

因为浏览器那段记忆太深,ActiveX/OCX 常被误认为“古早 Web 技术”。 但它其实被用在更广的地方:

  • 桌面应用
    • VB6
    • MFC/C++
    • Access 表单
    • Office/VBA 周边
  • 浏览器/公司内部 Web
    • 在 IE 里内嵌的查看器
    • 签名组件
    • 文件传输组件
    • 周边设备连接组件
  • 既有 .NET 应用
    • 从 WinForms 包装、沿用既有 ActiveX 控件
    • 把既有 COM 资产当作 UI 组件继续使用

这里重点是:ActiveX 不是“网络专属”的技术。 只是它在 IE 上名声太大,让人误以为只是 Web 技术;实际上看成 Windows 的嵌入式组件技术 更贴近实务。

9. 为什么容易被混淆

9.1. 三个词不在同一层,却一起出现

  • COM 是 底层 的事
  • ActiveX 是 组件语境 的事
  • OCX 是 文件 的事

本来就不是同一层面的东西,但实务上常同时冒出来,对话很容易搅成一团。

9.2. “ActiveX”一词用得稍宽

“COM”的含义还算固定。 “ActiveX”则不论历史上还是实务上,使用范围都稍微宽一些。

不同人可能在指:

  • 控件本身
  • .ocx 文件
  • 在 IE 上运行的老组件
  • 一般以 COM 为基础的嵌入式组件

这时对话就更容易混乱。

9.3. 看到 .ocx 就想全部叫 ActiveX

这种心情能理解,日常对话通常也没问题。

但在迁移或排查场景下,还是要分开看:

  • 它是 UI 组件吗
  • 运行在哪个宿主上
  • 需不需要注册
  • 32bit/64bit 怎么配
  • 有没有浏览器依赖

如果不先分清楚,后面就会实实在在地踩坑。

10. 在当下实务中该怎么看

看到 COM/ActiveX/OCX 不必马上全盘否定;但把它们一视同仁也很危险。

浏览器侧的 ActiveX 依赖

这一块应该先用更严格一点的角度看:

  • 已不属于现代浏览器开发的主流
  • 在兼容运维场景下会提到 IE 模式,但它是 为了向后兼容的桥梁,不是新项目的前提
  • 不建议以它作为新系统的前提

也就是说,Web 端的 ActiveX 应该从“怎么脱离”的角度想,而不是“怎么延续”

桌面端的 ActiveX/OCX 依赖

这一块可以务实地判断:

  • 在既有宿主中稳定运行
  • 发布对象范围明确
  • 厂商或自家的维护前景有保障
  • 注册、依赖 DLL、位数(bitness)的前提都清楚

条件齐备的话,继续使用 完全是合理的选项。

反之,若出现:

  • 想在 64bit 进程直接加载 32bit OCX
  • 想把周边全部改成 .NET
  • 每次部署与注册都出问题
  • 还残留浏览器依赖

就该分别考虑 保留、封装、替换 的策略。

所以在今天的实务中,并不是“有 ActiveX 就是错”,而是 边界要划在哪里。 与其把它当作古老技术,不如当成 既有系统的对接面 来看,会更好处理。

11. 常见误解

误解 1:COM = ActiveX

不是。 COM 是底层,ActiveX 是在其之上的控件语境。

误解 2:ActiveX = Internet Explorer

不是。 它在 IE 上出名是事实,但 ActiveX 并不是浏览器专属。

误解 3:ActiveX = OCX

实务上几乎被当作同义词使用,但严格来说不同。 ActiveX 是语境或组件层面的事,OCX 是实际会看到的扩展名。

误解 4:OCX 不就是 DLL 吗

粗略说是接近,但在排查场景下不要这样粗略处理。 光看“.dll”看不出角色,但“.ocx”已经很有控件的味道。

误解 5:COM 是已经死掉的技术

至少在 Windows 世界这样说太粗糙。 它在台面上没那么显眼,但在设计与互操作的语境中仍然会出现。

12. 排查时的检查清单

看到 COM/ActiveX/OCX,先按下面的顺序确认会比较好整理:

  1. 这是什么组件
    • UI 控件?
    • 查看器?
    • 设备连接?
    • Office/Access 集成?
  2. 运行在哪里
    • Access/VBA?
    • VB6/MFC?
    • WinForms?
    • IE/IE 模式?
  3. 文件与标识符是什么
    • .ocx / .dll / .exe
    • ProgID
    • CLSID
    • Type Library
  4. 注册与部署怎么做
    • 要不要 regsvr32
    • 有没有依赖 DLL
    • 要不要管理员权限
  5. 位数(bitness)对得上吗
    • 32bit?
    • 64bit?
    • 需要跑在同一进程吗
  6. 未来打算怎么处理
    • 就这样保留
    • 做边界封装
    • 直接替换

不先做这些,直接喊出“有 ActiveX 所以要全面重写”,多半会原原本本地踩上老坑。 没必要专门跑去踩雷。

13. 总结

最粗略但最实务的说法:

  • COM 是底层
  • ActiveX 是以 COM 为基础的嵌入式组件语境
  • OCX 是 ActiveX 控件实现常见的文件

也就是说:

  • “COM”在讲机制
  • “ActiveX”在讲组件
  • “OCX”在讲文件

把这 3 件事分清楚,下面这些就会明显好判断:

  • 这只是个 .ocx
  • 还是整个 COM 的问题
  • 是浏览器依赖的 ActiveX
  • 还是桌面上可以保留的组件

遗留技术之所以难处理,不是因为名字老,而是 底层、组件、文件常常在同一段对话里出现。 一旦把结构看清楚,问题其实相当可控。

14. 参考资料

共享相同标签的最新文章。可以围绕相近的主题进一步加深理解。

常见问题

汇总了咨询这一主题时常见的问题。

OCX 是什么?
OCX 是 ActiveX 控件实现常用的扩展名。在 Windows 现场看到 .ocx 文件,很大概率是嵌入式控件类的 COM 组件。常见场景包括厂商 SDK 的发布物、VB6 / Access / MFC 的老项目、安装程序里会被注册的文件、需要 regsvr32 注册的组件。重点是 OCX 是文件形式,不是概念本身。
COM、ActiveX、OCX 三者是什么关系?
最简单的记法是:COM 是机制、ActiveX 是组件的语境、OCX 是文件。COM 是 Windows 上组件之间互操作的二进制契约底层;ActiveX 是以 COM 为基础、可嵌入宿主使用的控件语境;OCX 则是 ActiveX 控件实现常见的扩展名。这三个词本来就不在同一个层面,却常在同一段对话里一起出现,所以容易混淆。
OCX 和 DLL 有什么不同?
“.ocx”相当明确地暗示着“这是 ActiveX 控件”,而“.dll”可能是普通库、COM server,也可能是 ActiveX 周边的依赖 DLL,光看扩展名还判断不出角色。实务上常见的组合是主角的 OCX 搭配辅助的 DLL,例如 vendorcontrol.ocx 加上 vendorhelper.dll。粗略说 OCX 算是接近 DLL 的一种,但在排查或迁移场景中,建议把两者的角色分开看。
ActiveX 只是 Internet Explorer 的技术吗?
不是。ActiveX 在 IE 上出名是事实,但它并非浏览器专用。ActiveX 控件也被用在 Access 表单、VB6 应用、MFC 的容器、Office / VBA 周边,还能从 WinForms 通过 COM 包装器使用。把它看成 Windows 应用长期使用的嵌入式组件技术更贴近实务。不过浏览器侧的 ActiveX 依赖已不属于现代主流,应该从“怎么脱离”的角度考虑;桌面侧则可以务实地判断保留、封装、替换的策略。

作者简介

本文作者的个人简介页面。

Go Komura

小村软件有限公司 代表

以 Windows 软件开发、技术咨询与故障排查为中心,擅长难以复现的故障调查,以及既有资产仍在运行的项目。

返回博客列表