更新记录(仅首版,2026年08月28日 发布)
- 首次发布
「双击 Word 规格书里的表格,菜单竟然变成了 Excel 的。」这是把表格作为 OLE 对象、而不是单纯的图片放进文档时才会有的行为。
OLE 是 Object Linking and Embedding(对象的链接与嵌入)的缩写。它把其他应用程序创建的文档数据,以嵌入或链接的形式整合进作为容器的文档。技术上的实体,是能够嵌入文档或被文档链接的 COM 对象。12
理解的起点是「数据本体究竟在哪里」。想清楚这一点,就能理顺文档为什么会变大、服务器迁移后链接为什么会断、表格明明看得见却为什么无法编辑。
本文面向中小企业的信息系统负责人和业务应用开发者。先比较嵌入与链接,再依次讲日常操作、按症状分类的处理办法,以及 Access 与安全方面需要注意的地方。COM、结构化存储等内部结构集中在第 7 章,今后的维护与设计判断集中在第 8 章。
1. 先说结论:嵌入是「文档内的副本」,链接是「指向别处的引用」
嵌入与链接的区别,在于数据本体保存在什么地方。可移植性、文件大小、更新方式,都由这个区别决定。3
| 比较的角度 | 嵌入(Embedding) | 链接(Linking) |
|---|---|---|
| 数据本体的存放位置 | 作为容器的文档内部 | 链接源。多数情况下是另一个文件 |
| 文档一侧保存的内容 | 数据本体与管理信息,通常还有显示缓存 | 链接源的名称与位置、更新设置等管理信息,通常还有显示缓存 |
| 修改原始数据时 | 不会体现到嵌入的副本上 | 可按链接的更新设置体现出来 |
| 编辑对象时 | 编辑的是文档内的副本,不影响原始数据 | 编辑的是链接源的数据 |
| 文档大小 | 因为持有本体的副本,一般比链接同样内容时更大 | 因为本体不在文档内,容易保持较小 |
| 交给另一台 PC | 独立于原文件。但编辑仍需要创建源应用程序 | 接收方也必须能够追踪到链接源 |
| 主要注意事项 | 文件膨胀、对创建源应用程序的依赖 | 链接断开、更新设置、对创建源应用程序的依赖 |
嵌入适合希望文档独立于原文件的场景。链接适合多个文档共享同一份数据、并希望原始数据的修改能够体现出来的场景。不过,链接的更新未必是自动的。到底是自动更新还是手动更新,由文档一侧的设置决定。456
flowchart TB
accTitle: 嵌入与链接的区别
accDescr: 嵌入把数据本体整个保存在作为容器的文档内部,因而自成一体,代价是文档变大;链接只在文档中放置引用、更新设置和通常的显示信息,数据本体留在链接源文件里,因此文档较小,并可按链接更新的设置(自动或手动)把链接源的修改体现出来
doc["作为容器的文档(Word 文档等)"] --> emb["嵌入:连数据本体一起保存"]
doc --> lnk["链接:引用、设置与显示信息(通常)"]
emb -.-> self["自成一体但会变大"]
lnk --> src["链接源文件(本体在这里)"]
src -.-> upd["可体现原始数据的修改(取决于设置)"]
图 1:文档内部持有本体,还是引用别处的本体。这个区别决定了大小、更新与交付方面的性质。
「数据在文档里」和「在任何 PC 上都能编辑」是两回事。另外,只要显示缓存还在,即使无法使用创建源应用程序或链接源,也可能仍然显示出最后一次的外观。把「看得见」「能编辑」「已更新到最新」分开来考虑,是排查的基本功。78
图中实线表示始终成立的关系,虚线表示带条件的关系(成立条件写在详情页各关系的说明中)。关系的完整列表(共 25 条,附依据与确信度)以及主要概念的定义,汇总在知识地图详情页(日文)。数据:JSON-LD / Turtle
2. 它用在哪里,又是怎样进入文档的
2.1 会在 Word、Excel、Access 和老旧业务文档中遇到
OLE 是自 1990 年代起支撑 Windows 文档文化的技术。它的机制至今仍在运转,但与其说是新设计中会主动采用的技术,不如把它理解成会在现有文档和数据库里遇到的技术,这样更贴近实务。
| 场所 | 生成 OLE 对象的入口 | 内容举例 |
|---|---|---|
| Word / Excel / PowerPoint | 「插入」→「对象」、「选择性粘贴」 | Excel 工作表、Word 文档、图形、公式 |
| Access | OLE 对象型字段 | 图像、Excel 工作表、各类文件 |
| 格式文本(RTF)文档 | 过去在写字板等程序里做过的粘贴 | 图形、其他应用的对象 |
| 老旧报表与规格书 | 以前的负责人做的嵌入 | 以「双击打开」为前提的数据 |
用 OLE 对象型保存员工照片和产品图片的 Access 数据库,也是典型的现有资产。这类用途存在文件膨胀的问题,第 5 章会讨论迁移的判断。9
2.2 「插入对象」与「选择性粘贴」
在「插入对象」中,可以选择新建一个对象,或者由现有文件生成对象。还有「显示为图标」这样的显示方式。
在「选择性粘贴」中,除了数据的格式之外,还要选择做成嵌入还是链接。这里列出的「~ 对象」,就是以 OLE 方式粘贴的选项。它与单纯当作图片粘贴不同,保存的数据不同,之后的编辑方式也不同。1011
这两者对应 OLE 的标准对话框 Insert Object 与 Paste Special,MFC 中也准备了用于显示它们的类。从复制粘贴或拖放生成对象的路径,与直接由已注册的类或文件生成对象的路径有什么不同,将在 7.1 中说明。1012
3. 双击之后到底发生了什么
3.1 装载方是「容器」,负责编辑的应用是「服务器」
当 Word 文档中有一张 Excel 表格时,Word 是作为容器的 OLE 容器,负责编辑表格的 Excel 则是 OLE 服务器。在同一份文档里处理来自多个应用的数据,这样的文档在 OLE 中称为复合文档。12
并不是 Word 自己实现了 Excel 的全部编辑功能。这是一种在操作对象时借用创建源应用程序功能的机制。因此,即便数据本体已经保存在文档内部,编辑时依然需要创建源应用程序。
3.2 双击执行的是对象自己决定的「主动词」
OLE 对象会把可以对自己执行的操作定义为动词(verb)。表格对应「编辑」,声音对应「播放」,诸如此类。
容器应用在接到双击等操作后会调用 IOleObject::DoVerb。决定默认操作即主动词(OLEIVERB_PRIMARY)内容的,不是容器而是对象一侧。DoVerb 会自动启动 OLE 服务器应用,并执行与该对象相称的操作。双击并不总是意味着「编辑」。13
3.3 能在 Word 内部编辑的情形,与另开窗口的情形
只要嵌入对象和容器双方都支持 In-Place Activation(就地激活),就可以在容器的窗口内部编辑。菜单栏会被替换成把容器和服务器两边菜单合成起来的复合菜单栏。Word 里会出现 Excel 的编辑菜单,正是这个机制。点击对象外侧就会取消激活,回到原来的菜单。14
sequenceDiagram
accTitle: 从双击到 In-Place Activation
accDescr: 容器应用接到双击后通过 IOleObject 的 DoVerb 执行主动词,OLE 随之启动服务器应用;当容器与服务器双方都支持 In-Place Activation 时,嵌入对象会在容器窗口内部合成菜单进行编辑,点击外侧则取消激活并回到原来的菜单(若不支持,则改为在另一个窗口中编辑)
participant U as 使用者
participant C as 容器应用(Word 等)
participant S as OLE 与服务器应用
U->>C: 双击嵌入对象
C->>S: 用 DoVerb 执行主动词
alt 双方都支持 In-Place Activation
S->>C: 启动服务器并合成菜单
U->>C: 就地编辑
U->>C: 点击对象外侧
C->>S: 取消激活并回到原菜单
else 有一方不支持
S->>C: 在另一个窗口中编辑
end
图 2:要就地编辑嵌入对象,需要容器与服务器双方都支持。不支持时就改为在另一个窗口中编辑。
打开的方式,取决于对象的种类、所执行的动词以及应用的支持情况。
| 条件 | 打开方式 |
|---|---|
| 嵌入,且双方都支持 In-Place Activation,执行就地编辑时 | 在容器的窗口内部编辑 |
| 虽然是嵌入,但有一方不支持 In-Place Activation 时 | 在另一个窗口中编辑 |
嵌入且指定了 OLEIVERB_OPEN 时 |
在另一个窗口中打开 |
| 链接对象时 | 始终在另一个窗口中打开 |
In-Place Activation 是以嵌入为前提的机制,不用于链接。而且对容器和服务器双方来说,实现它都是可选的。仅凭「同一份文档打开方式却不一样」,还不能判定为故障。11413
4. 从症状入手排查:不更新、体积大、打不开
4.1 表格看得见,链接源的修改却没有体现出来
先确认链接源的位置,以及链接的更新方式。链接在文档一侧持有的不是数据本体,而是链接源的名称与位置、更新设置等管理信息,通常还有显示缓存。155
追踪链接源这项工作,由 COM 的一个部件——名字对象(moniker)来承担。文件服务器迁移、文件夹改名、共享路径变更、原文件被删除等情况会让变更后的位置无法再被追踪到,链接解析随之失败。这就是链接断开。
此时只要保存了显示缓存,文档里就会留下旧的表格。表格显示得出来,并不能证明链接是正常的。如果对象是以不带缓存的方式创建的,连最后那份显示也不会留下。78
处理办法是在文档的「编辑链接」中,把链接源路径改指到新位置。路径正确却仍不更新时,也有可能只是被设成了手动更新,因此要一并确认更新方式。链接源的修改在什么时候体现出来,取决于自动更新还是手动更新的设置。6
如果大量使用链接的文档很多,就要把迁移前的清点和迁移后的链接更新一并纳入文件服务器迁移计划。可能的话,也把批量更新一起规划进去。等迁移之后才发现问题,就只能逐份文档去找以前的负责人当初用的链接源了。
4.2 Word 或 Excel 文档大得异常
先确认是否真的需要重新编辑,再重新审视文档内部持有数据本体的必要性。嵌入会把本体复制一份保存在文档内部,因此一般比链接同样内容时更大。通常还会保存显示缓存,所以文档里未必只有编辑用的数据。47
如果一份嵌入了大量表格的报告变得很大、打开也很慢,就该怀疑这个结构。处理办法要按使用方式来选。
| 这份数据要怎么用 | 调整方式 |
|---|---|
| 不需要在文档上重新编辑 | 以图片形式粘贴 |
| 想共享原始数据并体现其修改 | 另行共享原文件,文档中放置链接 |
| 原始数据另行管理,文档里只要有外观即可 | 共享原文件,文档中只放图片 |
不过,为了缩小体积而改成链接,管理链接源的责任就会随之增加。对外分发的文档中引用很容易失效,因此单纯「把所有嵌入都改成链接」并不合适。
4.3 双击也打不开、无法编辑
首先确认该对象的创建源应用程序在当前 PC 上是否也存在。嵌入的自成一体说的是数据保存位置,并不意味着连编辑功能也装进了文档里。
没有创建源应用程序时,只要保存了显示缓存,就还能利用那份显示。缓存下来的显示数据在设计上就是为了在服务器应用未启动或不可用时,仍能由容器加以利用。7
不过,如果是以「显示为图标」的方式粘贴的,即使看得见图标也无法确认内容。对于本身不带缓存的对象,连最后的外观也不会留下。是否带有缓存,取决于创建时对 OLERENDER 的指定。8
创建源应用程序存在却打不开时,按下面的顺序排查。
- 确认应用的版本兼容性。有时需要转换种类,OLE 也提供了用于转换的标准对话框。
- 确认 COM 类注册(CLSID)是否缺失或损坏。有时需要通过重新安装应用等方式修复注册。
- 确认安全设置造成的阻止,以及文档本身是否损坏。10
对于来源不明的文档,不要优先想着把它打开,而应采取不激活其中对象的做法。安全方面的处理会在第 6 章说明。
5. 在 Access 中要区分「只是想存起来」还是「需要 OLE 的行为」
5.1 把图像放进 OLE 对象型容易膨胀
Access 的 OLE 对象型,是用来把 Excel 电子表格、Word 文档、图形、声音等嵌入到表或与表建立链接的字段类型。上限约为 1GB。9
如果仅仅为了保存员工照片和产品图片就使用这个类型,存储效率就会成为问题。Microsoft 说明称,附件型比 OLE 对象型更灵活,而且不会生成原文件的位图图像,因此存储的使用也更高效。9
不过,改用附件型并不等于容量上限就消失了。
| 项目 | 约束与性质 |
|---|---|
| 可使用附件型的格式 | .accdb |
| 数据库整体的最大大小 | 2GB |
| 单个附件文件的最大大小 | 256MB |
| 图像的显示 | BMP、PNG、JPEG 等无需额外软件即可显示 |
这些是 Access 附件型的约束。它们与 OLE 对象型约 1GB 的上限,针对的对象并不相同。16
5.2 只是存储的话,改用附件型或文件夹加路径管理
如果是只保存图像和文件的新设计,没有必要选择 OLE 对象型。可以考虑附件型,或者把文件放到文件夹里、数据库中只保存路径的设计。对现有数据库来说,这两者也是迁移目标的候选。
另一方面,如果需要链接、激活等 OLE 特有的行为,那就是另一回事了。这种情况下要连维持现状一起纳入判断。不要因为「是 OLE 对象型就立刻替换」,而应先分清究竟只是单纯的存储,还是确实需要让它作为对象运转。916
6. 安全:把普通的嵌入与 OLE 包分开对待
6.1 文档会成为执行其他应用的入口
在 OLE 中,其他应用的对象被带进文档,并在打开方的 PC 上运转。这个结构对攻击者来说同样是运载手段。
实际上,通过包含精心构造的 OLE 对象的 PowerPoint 文件等执行任意代码的漏洞 CVE-2014-4114,就被用在了定向攻击中。由于能够存放 OLE 对象的 Office 格式等都可能成为攻击路径,「本以为只是读一读文档」就变成了执行的入口。17
6.2 从组织层面禁止 OLE 包的激活
尤其需要留意的是 OLE 包(Object Packager)。这是一种把任意文件当作 OLE 对象包裹进文档的老旧机制,连可执行文件也能装进去。与 Object Packager 相关的远程代码执行漏洞,也已经公开。18
因此,通过注册表设置禁止在 Word、Excel、PowerPoint 中激活 OLE 包就成了一项加固措施。Microsoft 面向澳大利亚政府 Essential Eight 的指南,给出了用 Intune 把设置用的 PowerShell 脚本分发到整个组织的步骤。19
实际做法分为以下三点。
- 不打开、也不让别人打开来源不明文档中的对象。把激活当作与打开另一个文件同等分量的操作来对待。
- 从组织层面阻止 OLE 包的激活。日常工作中基本不会需要它,因此不能只依赖个人的注意力。
- 不要把内部文档中普通的嵌入与链接也一律禁止。要把包和被构造过的文档带来的风险,与现有的业务使用分开判断。
本文的结论不是「全面禁止 OLE」。与其把连普通 Excel 表格的嵌入都一律禁止、把业务停下来,不如集中处理来源不明的对象和 OLE 包——这才是本文的整理思路。
7. 内部结构:COM、结构化存储与名字对象各自的角色
从这里开始,是维护业务应用和调查文档资产时会用到的、偏实现层面的说明。把前面各种症状对应到「由哪个机制负责」。
7.1 支撑 OLE 复合文档的三大基石
OLE 复合文档建立在 COM、结构化存储与统一数据传输之上。对象除了 COM 的 IUnknown 之外,还会公开 IOleObject、IViewObject2 等复合文档专有的接口。链接对象还会再实现 IOleLink。2
| 基石 | 负责的事情 | 主要接口 |
|---|---|---|
| COM | 对象的实体,以及用于操作的契约 | IUnknown、IOleObject、IViewObject2、链接用的 IOleLink |
| 结构化存储 | 在文档内部做分层保存 | IStorage、IStream |
| 统一数据传输 | 由复制粘贴或拖放生成嵌入与链接的入口 | IDataObject |
在数据传输这条路径上,OLE 服务器用 IDataObject 提供自己的数据,并通过专用的剪贴板格式告诉容器:这份数据能否作为嵌入粘贴、能否作为链接粘贴。这就连接到了「选择性粘贴」里的那些选项。12
不过,并不是所有创建操作都要经过 IDataObject。从「插入对象」新建,或者由现有文件生成时,走的是直接依据已注册的类或文件创建对象的另一条路径。剪贴板与拖放本身的机制,在「剪贴板与拖放的机制」中讨论。
7.2 结构化存储是「一个文件内部的文件系统」
在结构化存储中,可以在一个文件内部构建相当于目录的存储(IStorage)与相当于文件的流(IStream)的层次结构。根存储之下,可以嵌套放入子存储和流。20
COM 提供的标准实现,就是复合文件(Compound Files)。这是一种不依赖 FAT、NTFS 等文件系统即可处理的单一文件格式,格式本身已作为 MS-CFB(Compound File Binary File Format) 公开。2122
容器负责准备对象的保存位置。用 IPersistStorage 做持久化的对象,会把自己的数据写入被交给它的 IStorage。如果实现使用的是 IPersistStream,保存位置就是 IStream。2
flowchart TB
accTitle: 复合文件的内部结构
accDescr: 复合文件在根存储之下拥有相当于目录的存储与相当于文件的流所构成的层次结构,用 IPersistStorage 持久化的嵌入对象保存在子存储中,用 IPersistStream 持久化的对象保存在流中;嵌入对象的存储可以带上用于标识创建源应用程序的 CLSID(也可能为空),显示缓存的流通常会被保存,但按创建时的指定也可能没有,它整体上就像一个文件内部的文件系统
root["根存储(文档本体)"] --> s0["流:正文数据"]
root --> st1["存储:嵌入(IPersistStorage)"]
st1 --> s1["流:对象的数据"]
st1 --> s2["流:显示缓存(通常)"]
st1 -.-> cls["可用 CLSID 标示创建源(可选)"]
root -.-> s3["流:IPersistStream 持久化"]
图 3:在文档内部构建层次结构,由对象自己保存数据。要区分使用存储的持久化和使用流的持久化。
目录项中可以带上用于标识对象创建源的 CLSID。只要嵌入的存储里有 CLSID,就能判断这个对象应该用哪个应用打开。不过 CLSID 也可能为空,显示缓存按创建时的指定也可能并不存在。228
7.3 即便变成了 .docx,OLE 的保存格式也没有消失
旧 Office 格式的 .doc / .xls,文件本身就是复合文件。文档正文作为流保存,嵌入对象作为子存储保存。
现行的 .docx / .xlsx 是基于 ZIP 的 Open XML 格式,但遗留的 OLE 嵌入二进制 oleObject*.bin,至今仍以复合文件格式保存。另一方面,新版 Office 文档之间的嵌入,有时会让 .xlsx 等文件原样收进 ZIP 里。22
| 被保存的东西 | 保存的容器 |
|---|---|
旧 Office 格式的 .doc / .xls |
整个文件就是复合文件 |
| 现行格式内部遗留的 OLE 嵌入 | ZIP 内的二进制是复合文件 |
| 新版 Office 文档之间的嵌入 | 也可能保持文件原样收进 ZIP |
也就是说,复合文件并不只是「过去的文档格式」,它作为一种嵌套的保存格式,也留在了现行文档的内部。
7.4 链接的位置由名字对象负责,更新由链接的设置管理
名字对象是 COM 中用来把对象的所在位置表示为名称、并在需要时加以解析的部件。这个解析过程称为绑定。链接对象使用名字对象,管理链接源的命名、追踪与启动。15
IOleLink 是向容器提供链接源管理功能的接口。容器可以根据它是否存在,判断这是嵌入还是链接。即使保存了包含链接的文档,链接的数据本体仍然保存在链接源。留在文档里的,是名称与位置、更新设置等链接自身的管理信息,通常还有显示缓存。15
这种分工,正好对应 4.1 的「表格看得见却不更新」。链接源解析失败就到不了本体,即使到得了,若是手动更新也不会自动更新。把位置的解析、更新设置和缓存的显示分开来查,原因就能理清。67
8. 现在该如何与它相处:不增加新的依赖,摸清已有的依赖
新设计中避免依赖 OLE 嵌入,现有资产则以「维持可以打开的环境」和「清点」来对待,这是基本方针。要不要继续使用,按场景逐一判断。
| 场景 | 推荐的做法 | 理由 |
|---|---|---|
| 新的文档流程 | 以图片形式粘贴、共享原文件等,不依赖嵌入。链接也控制在最小范围 | 避免文件膨胀,也避免对编辑环境产生新的依赖 |
| 新的业务应用想把其他应用的数据放进文档 | 与其实现 OLE 容器,不如按图像化、PDF 化、文件附件来设计 | 值得为此付出实现与维护成本的场景,如今几乎没有 |
| 现有的嵌入文档 | 维持可以打开的环境,重要文档同时保留 PDF 版本 | 即使数据在文档内部,创建源应用程序一旦消失也无法编辑 |
| 大量使用链接的文档与文件服务器迁移 | 把链接的清点与更新纳入迁移计划 | 迁移后若无法追踪到位置,链接就会断开 |
| 在 Access 中存放图像和文件 | 迁移到附件型或路径管理。需要 OLE 特有行为时另行判断 | 单纯的存放,用附件型更灵活也更高效 |
| Office 环境的安全加固 | 从组织层面禁止 OLE 包的激活 | 它是公开指南给出的加固措施 |
关于 Access 与安全的判断,分别与 Microsoft 的资料相对应。919
在长期保存中,不只是数据,能够打开它的环境同样是资产的一部分。随着应用的更新换代和操作系统的变化,「创建源应用程序还能用」这个前提会逐渐失去。除了保留重要文档的 PDF 版本之外,还需要用虚拟机维持可以打开的环境这类补救手段。
只要 Windows 继续守住向后兼容,OLE 的机制就会一直运转下去。但每一个对象能否打开,取决于创建源应用程序是否还在。只要能够确保这个前提,就没有必要急着全面废除。
清点时要摸清三样东西:存放链接源的服务器、包含嵌入的文档、使用 OLE 对象型的数据库。弄清这些依赖关系,就能把迁移、安全加固和数据迁移纳入计划。
9. 小结
OLE 对象,是用来把其他应用的文档数据以嵌入或链接方式加以处理的 COM 对象。嵌入把本体保存在文档内部,链接引用别处的本体。请先把这个区别记牢。245
其次,要把显示、编辑、更新分开来考虑。即使显示缓存还在,没有创建源应用程序也无法编辑;追踪不到链接源就无法更新。双击时的打开方式,也会随对象的种类与动词、以及对 In-Place Activation 的支持情况而变化。
新的做法上不要增加依赖,现有文档则要摸清并维持可打开的环境与引用目标。Access 里单纯的图像与文件存放,改用附件型或路径管理;OLE 包的激活,则从组织层面加以阻止。
COM、剪贴板与拖放,以及本文的复合文档,是 OLE 这个词的不同侧面。把组件基础、数据传输、向文档集成这三种角色分开来看,就更容易追查老旧业务资产内部到底发生了什么。
相关文章
- 什么是 COM / ActiveX / OCX - 区别与关系一次讲清
- 剪贴板与拖放的机制 —— 在业务应用中正确处理 OLE 数据传输
- COM STA/MTA 基础知识 - 线程模型与避免挂起的思路
- C# 操作 Excel 时 EXCEL.EXE 残留的问题 —— COM 引用的释放模式与替换判断
- 现在该如何对待 ActiveX / OCX - 保留、封装、替换的判断表
- VB6 / Access 业务应用的延续使用与迁移 —— 保留、封装、替换的判断表
相关咨询领域
小村软件有限公司承接与 OLE、COM 相关的遗留文档和数据库资产的调查与迁移(摆脱 Access 的 OLE 对象型、嵌入文档的清点与 PDF 化、链接断开的批量处理)、包含 COM 组件的业务应用的维护与改造,以及 Office 集成应用的设计。哪怕只是处在「这份文档双击之后到底发生了什么,我们也搞不清楚」的阶段,也欢迎来咨询。
参考链接
-
Microsoft Learn, OLE Background. 关于 OLE 来自 Object Linking and Embedding 的首字母缩写,OLE 文档(复合文档)整合来自多个应用的数据,容器与服务器的角色分工,In-Place Activation(可视化编辑)的概要,以及链接项不会被 In-Place Activation 的说明。 ↩ ↩2 ↩3
-
Microsoft Learn, Compound Documents. 关于 OLE 复合文档建立在 COM、结构化存储与统一数据传输之上,复合文档对象是可嵌入文档或被文档链接的 COM 对象并公开 IOleObject、IOleLink、IViewObject2 等专有接口,以及对象用 IPersistStorage/IPersistStream 管理自身的保存、由容器提供 IStorage 的说明。 ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Linking and Embedding. 关于复合文档的对象分为链接与嵌入两种,以及源数据保存位置的差异会影响可移植性、激活、更新与大小的说明。 ↩
-
Microsoft Learn, Embedded Objects (COM). 关于嵌入对象连同管理信息一起物理地保存在复合文档内部,比用链接持有时文档更大,源的修改不会体现到嵌入的副本上,以及交给其他 PC 也不会让链接损坏的可移植性和 In-Place Activation 这两项优点的说明。 ↩ ↩2 ↩3
-
Microsoft Learn, Linked Objects. 关于链接对象的源数据留在链接源、文档中只保存引用与显示用信息,文档大小得以保持较小,链接源的修改会体现到所有包含该链接的文档,以及激活链接会启动服务器应用的说明。 ↩ ↩2 ↩3
-
Microsoft Learn, OLEUPDATE enumeration (oleidl.h). 关于链接对象的缓存更新分为自动(OLEUPDATE_ALWAYS)与手动(OLEUPDATE_ONCALL)并分别对应链接对话框中自动更新与手动更新这两个选项,以及手动方式下只有在调用 IOleObject::Update 或 IOleLink::Update 时才会更新的说明。 ↩ ↩2 ↩3
-
Microsoft Learn, IOleCache interface (oleidl.h). 关于该接口提供对对象内部所缓存显示数据的控制,以及缓存下来的显示数据即使在服务器应用程序未启动或不可用时也能由对象的容器加以利用的说明。 ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, OLERENDER enumeration (oleidl.h). 关于该枚举类型表示创建嵌入与链接时所请求的本地缓存种类,以及指定 OLERENDER_NONE 时不请求本地缓存的绘制与数据获取能力(即不持有显示缓存)的说明。 ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, DataType property (Access). 关于 Access 的 OLE 对象型是用来把 Excel 电子表格、Word 文档、图形、声音等对象嵌入到表或与表建立链接的类型且上限约为 1GB,以及附件型比 OLE 对象型更灵活并且不会创建原文件的位图图像因而能更高效使用存储的说明。 ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Dialog boxes in OLE. 关于作为 OLE 标准对话框的 Insert Object(新建对象或由现有文件插入对象以及以图标显示)、Paste Special(选择格式并选择嵌入/链接/图标显示)、Change Icon、Convert(转换嵌入与链接项的种类)各自作用的说明。 ↩ ↩2 ↩3
-
Microsoft Learn, Selection.PasteSpecial method (Word). 关于相当于 Word「选择性粘贴」的 VBA 方法,除了指定粘贴格式之外,还能通过 Link 参数控制以链接方式粘贴、通过 DisplayAsIcon 参数控制以图标显示的说明。 ↩
-
Microsoft Learn, Creating Linked and Embedded Objects from Existing Data. 关于嵌入与链接对象的创建始于通过剪贴板或拖放进行的 IDataObject 数据传输,OLE 服务器按保真度顺序提供用于创建嵌入与链接的专用剪贴板格式,以及可用相当于「选择性粘贴」的命令选择嵌入或链接的说明。 ↩ ↩2
-
Microsoft Learn, IOleObject::DoVerb method (oleidl.h). 关于动词(verb)是对象所定义的动作,决定双击时行为的 OLEIVERB_PRIMARY 由对象而不是容器决定,DoVerb 会自动启动 OLE 服务器应用,以及 OLEIVERB_OPEN 会让嵌入对象在另一个窗口中打开的说明。 ↩ ↩2
-
Microsoft Learn, Implementing In-Place Activation. 关于 In-Place Activation 让嵌入对象可以在不离开容器文档的情况下操作,激活时菜单会替换成合成了容器与服务器双方菜单的复合菜单栏并在取消激活时恢复原状,实现对容器与服务器双方都是可选的,以及链接对象始终在另一个窗口中打开的说明。 ↩ ↩2
-
Microsoft Learn, Linked Objects and Monikers. 关于链接对象通过名字对象为源命名,并负责找到源并启动它的绑定,IOleLink 提供链接身份的识别与链接源的管理功能,以及保存包含链接的文档时数据保存在链接源、文档一侧只保存名称与位置信息的说明。 ↩ ↩2 ↩3
-
Microsoft Learn, Attachment object (Access). 关于附件型可用于 .accdb 格式的数据库,可附加数据的上限为数据库最大大小 2GB 而单个文件最大为 256MB,以及 BMP、PNG、JPEG 等图像格式无需额外软件即可显示的说明。 ↩ ↩2
-
Microsoft Learn, Microsoft Security Bulletin MS14-060 (CVE-2014-4114). 关于 OLE 是让复合数据得以创建与编辑的技术,通过诱使打开包含精心构造的 OLE 对象的文件即可以当前用户权限执行任意代码的漏洞,能够存放 OLE 对象的 Office 格式等众多文件格式都可能含有恶意 OLE 对象,以及当时已确认存在利用该漏洞的有限定向攻击的说明。 ↩
-
Microsoft Learn, Microsoft Security Bulletin MS12-002. 关于 Windows Object Packager 是创建可插入文件的包的工具,以及因其注册与实现不当而导致的远程代码执行漏洞(CVE-2012-0009)及其规避措施的说明。 ↩
-
Microsoft Learn, Essential Eight user application hardening. 关于作为对应澳大利亚政府 Essential Eight 的加固指南,其中给出了用 Intune 分发 PowerShell 脚本以写入注册表项、从而阻止在 Excel、PowerPoint、Word 中激活 OLE 包的步骤的说明。 ↩ ↩2
-
Microsoft Learn, IStorage interface (objidl.h). 关于结构化存储让信息可以在一个文件内部分层存放因而被称为「文件中的文件系统」,存储相当于目录、流相当于文件,以及根存储之下可以嵌套子存储与流的说明。 ↩
-
Microsoft Learn, Compound Files. 关于复合文件是 COM 提供的结构化存储标准实现,它运行在既有的扁平文件系统之上并且是可在 FAT、NTFS、Mac 的文件系统之间互相打开的文件系统无关格式,以及可通过标准接口枚举与引用其内部对象的说明。 ↩
-
Microsoft Learn, [MS-CFB]: Compound File Binary File Format. 复合文件二进制格式的公开规范。关于在一个文件内部存放应用程序专有数据流的类文件系统结构的定义,以及用于枚举存储与流的目录项及其 CLSID 字段的说明。 ↩ ↩2 ↩3
相关文章
共享相同标签的最新文章。可以围绕相近的主题进一步加深理解。
剪贴板与拖放如何工作 ── 在业务应用中正确处理 OLE 数据传输
粘贴 Excel 表格时格式散架;关闭源应用后就再也贴不上——两者都来自剪贴板把同一内容同时放成多种格式。本文说明标准格式、延迟渲染、OLE 拖放,以及管辖剪贴板历史和云同步的策略。
WinRT 就是 COM —— IInspectable、.winmd、语言投影,以及 WinUI 至今仍立在二进制契约之上的原因
WinRT 不是托管运行时,而是在 COM 之上加了元数据(.winmd)与语言投影的 ABI。本文从 IUnknown 与 IInspectable 的关系,一直讲到桌面应用里 HWND 初始化与 package identity 的卡点。
今日的 Windows 外壳集成 ── 上下文菜单、文件关联,以及 Windows 11 改了什么
说明 Windows 11 上下文菜单为何藏到「显示更多选项」后面,从扩展名→ProgID→verb 关联基础、传统外壳扩展注意事项,到 IExplorerCommand 与 MSIX/sparse package 路径。
VB6 / Access 业务应用的续用与迁移 ── 保留、封装、替换的判断表
VB6 应用程序与 Microsoft Access 业务应用该如何判断是直接保留、只封装一部分继续用,还是全面替换?本文整理运行环境现状、ACE 的 32bit/64bit 问题、共享文件夹多人使用风险,以及升级到 SQL Server 的判断表与实务步骤。
委托开发 Windows 应用程序前该梳理的事项
在委托外包开发 Windows 应用程序之前,梳理现有软件改造、设备联动、COM/ActiveX、发布与更新、维护等需要注意的要点。
相关主题
与本文相近的主题页面。以本文为起点,可以进一步了解相关服务和其他文章。
Windows 技术主题
汇整 KomuraSoft LLC 关于 Windows 开发、故障调查与既有资产活用文章的主题中心。
ActiveX 迁移
整理保留、包装或替换 COM / ActiveX / OCX 资产的阶段性判断的主题页面。
与本主题相关的服务
本文与以下服务页面相关联,欢迎从最接近的入口查看。
Windows 应用程序开发
支持包含常驻处理、设备联动、运行日志与可维护结构的 Windows 桌面应用程序。
既有资产活用 & 迁移支持
在持续活用 COM / ActiveX / OCX 资产、原生代码与 32 位依赖的同时,协助规划阶段性的迁移。
常见问题
汇总了咨询这一主题时常见的问题。
- 嵌入和链接到底有什么区别?
- 区别在于数据本体放在什么地方。嵌入(Embedding)会把对象的数据本体整个保存到作为容器的文档内部。文档因此独立于原文件,交给别的 PC 也不会出现引用断开的情况(不过要编辑,接收方的 PC 上同样需要创建源应用程序。没有的话,只有在保存了显示缓存时才能看到那份缓存,而以图标方式显示的对象连内容都无法确认)。代价是文件会变大,而且修改原始数据也不会体现到文档里。链接(Linking)只在文档中放置引用(链接源的名称与位置)、更新设置和用于显示的信息,数据本体仍留在链接源文件里。文档保持较小,链接源的修改可以体现到文档中(是自动还是手动,取决于链接的更新设置),但一旦链接源被移动或改名、无法再追踪到去向,就会出现链接断开。用哪种方式粘贴,可以在「选择性粘贴」或「插入对象」对话框里选择。
- 为什么双击文档里的嵌入对象也打不开、无法编辑?
- 最常见的原因是当前 PC 上没有安装创建该对象的源应用程序。编辑嵌入对象要靠启动创建源应用程序(OLE 服务器)来完成,因此没有这个应用时,只有在保存了显示缓存的情况下才能显示那份缓存,而以图标方式显示时连内容都看不到。如果创建源应用程序在却仍然打不开,请按顺序怀疑这几点:因版本差异而需要「转换」的情况、可通过重新安装等方式修复的 COM 类注册(CLSID)缺失或损坏、文档本身损坏,以及安全设置阻止了激活。
- 为什么 Word 或 Excel 文件带了嵌入对象后会大得异常?
- 因为嵌入是把数据本体复制一份保存到文档内部的方式。与用链接持有同一对象的文档相比,持有嵌入的文档一般更大。此外文档中通常除了编辑用的数据本体,还会保存显示缓存(是否持有缓存由创建时的指定决定)。想让文件变小,可选的做法有:改用链接而不是嵌入、以图片形式粘贴(接受不再需要重新编辑这一前提)、把原文件另行共享而文档中只放链接或图片。不过链接需要有人管理链接源,因此不适合用于对外分发的文档。
- 迁移文件服务器之后,文档里的链接对象不再更新了,这是为什么?
- 因为链接对象在文档内持有的不是数据本体,而只有链接源的名称与位置信息(名字对象)、更新设置和显示缓存。文件服务器迁移、文件夹改名、共享路径变更等原因会让链接源的位置发生变化,一旦无法再追踪到变更后的位置,链接解析就会失败,文档里只剩下旧的显示缓存(如果对象是以不保存缓存的方式创建的,连这份显示也不会留下)。要修复,需要在各个文档的「编辑链接」中把链接源路径改指到新位置。另外,如果路径正确却仍不更新,也可能并不是链接断开,而只是链接被设成了手动更新,所以请一并确认更新方式的设置。文档数量很多时,请在迁移前先清点包含链接的文档,并尽可能把链接的批量更新纳入计划。
- 听说 OLE 对象存在安全风险,还能继续用吗?
- 「把别的应用的对象带进文档,并在打开方的机器上执行」这一 OLE 结构,对攻击者来说同样是方便的运载手段,利用精心构造的 OLE 对象实现任意代码执行的漏洞,确实被用于真实的定向攻击。尤其是可以包裹任意文件的 OLE 包最为危险,澳大利亚政府的 Essential Eight 等公开指南建议通过注册表设置禁止在 Word、Excel、PowerPoint 中激活 OLE 包。并不需要连内部文档中普通的嵌入与链接也一律禁止;比较现实的折中做法是:不打开来源不明文档中的对象,并从组织层面阻止 OLE 包的激活。