Windows XP 传奇般的兼容性,部分源于微软对老应用撒了谎 Windows XP 之所以能如此出色地运行老软件,部分原因在于它内置了一个隐藏的问题应用数据库。当 Windows 发现其中某个应用时,可以向应用隐瞒 Windows 版本,甚至只针对该程序,为它提供旧版 Windows 95 的内存管理器。
如果你当年使用过 Windows XP,那么即便仅仅因为它几乎能运行你安装的所有软件——包括在 2001 年 XP 发布前多年就编写的游戏和商业软件——你可能至今仍是它的粉丝。许多应用从未针对 XP 更新,却依然可以运行!
Windows XP 的 Bliss 壁纸 | 图片来源:Microsoft / Charles O’Rear微软工程师 Raymond Chen 已从事 Windows 开发超过 30 年。他在 2003 年写道,XP 将兼容性修复列表保存在 C:\WINDOWS\AppPatch 文件夹中,并以二进制格式存储,“以便快速扫描。”
让我惊讶的是,Windows 找到匹配项后所做的事情。它可以只针对某个应用改变 Windows 的工作方式,而且只在该应用运行期间生效。这听起来像是 AI 会做的事,但当然,那可是 25 年前,一切都纯粹依靠人类智慧。
微软将这个列表称为应用程序兼容性数据库,它是一个带有 .sdb 扩展名的索引二进制文件。在 XP 中,主数据库是 Sysmain.sdb。微软表示,操作系统发布时其中大约包含 200 项兼容性修复。
对于应用程序,Windows 不会只查看其 .exe 文件名。XP 会根据文件大小、校验和、版本及日期匹配应用,甚至还能检查应用文件夹中的其他文件。这样,某项修复就可以只针对某个版本的程序,而不会影响运行正常的新版本。
Windows 找到匹配项后,就会应用微软称为 shim 的兼容性垫片。当应用调用 Windows API 时,Windows 会先通过一个小型存根函数转发该调用。这个函数可以调整应用发送的内容、修改 Windows 返回的结果,或在调用正确的 Windows 函数前运行自己的代码。
例如,有些应用只有检测到特定的 Windows 版本才会运行。Win98VersionLie 之类的 shim 会向应用返回 Windows 98 的版本信息,无论电脑实际运行的是哪个 Windows 版本,从而解决这一问题。
没错,Windows 对应用撒了谎,而应用对此毫不知情。
Windows XP 关机对话框。图片来源:Windows LatestChen 并不赞成开发者依赖这种机制。他在 2010 年的一篇文章中表示,如果某个程序只有在应用 VersionLie 后才能运行,那么开发者就应该修复版本检查,因为兼容模式“是为客户准备的,而不是为程序准备的。”
顺便一提,兼容模式并不是旧版 Windows 的迷你版本。每种兼容模式都是一组 shim 和标志,而 XP 的 Windows 95 模式包含大约 50 项最常见的修复。
伪造版本号是一回事,但 Chen 最喜欢的 shim 是 EmulateHeap。用他的话说,它“会用 Windows 95 堆管理器的精确副本替换标准堆。”
堆是程序向 Windows 借用内存的机制。有些老应用的编写方式使其过度依赖 Windows 95 处理内存的方式,因此当运行在更新版本的系统(例如 XP)上时就会崩溃。
因此,Windows 没有告诉用户这个应用写得很糟,而是给该应用提供了它所熟悉的内存管理器。
早在 XP 之前,微软就已经在做类似的事情。微软前程序员 Joel Spolsky 曾写道,SimCity 会读取刚刚释放的内存,因此 Windows 95 内置了一段专门查找 SimCity 的代码,并让内存分配器以特殊模式运行,不会立即释放内存。
另一方面,这也涉及安全问题。Chen 在 2017 年的一篇文章中解释说,Windows 2000 兼容模式会让程序按照 Windows 2000 的规则加载 DLL,而这些规则早于更安全的 SafeDllSearchMode 设置。微软之所以这样做,是为了兼容依赖这些规则的应用。
Chen 将其称为“逐 bug 兼容”,并指出,一个供应商如果超过 15 年都没有修复自己的应用,现在也不会突然修复它。
不过,shim 也不是万能的。Chen 表示,它们只能在应用自身的进程内发挥作用,因此不会改变程序与系统其他部分之间的安全边界,也无法帮助解决不兼容的内核模式驱动程序。
那么,微软为什么不直接阻止那些依赖未公开功能的应用?Chen 在 2003 年的文章中表示,每个被阻止的应用“都会成为人们不升级到下一版 Windows 的又一个理由。”
他写道:“只需要一个不兼容的程序,就足以让一次升级变得令人扫兴。”
Chen 请读者设想一下,自己是一名 IT 管理员,而公司的文字处理软件无法在 XP 上运行。供应商可能会为 2.0 版本的每个副本收取 150 美元。用 Chen 的话说,“恭喜你,升级到 Windows XP 的成本刚刚变成了原来的三倍。”而这还得建立在供应商仍然营业的前提下。

如果你想起如今每个应用都变成订阅制的日子,也完全不孤单!
此外,Chen 还回忆起微软安装团队进行的一项调查:几乎每家公司至少都有一个“无法舍弃”的程序(也就是公司没有它就无法正常运转的应用),通常是某个开发者已经离职的内部 Visual Basic 应用。你会为了升级整个办公室到 XP,而舍弃业务运行所依赖的唯一应用吗?当然不会。在我看来,微软比任何人都清楚这一点。
XP 还为微软提供了更整洁的方式来管理这些兼容性技巧。据 Chen 介绍,许多兼容性修复被移入 AppPatch 文件夹中的 DLL,因此“兼容性变通方案不再玷污操作系统的核心文件。”
微软多年来也一直为 XP 提供新的修复。2011 年 4 月的应用程序兼容性更新,将 XP SP3 中的 Sysmain.sdb 替换成了一个大小为 1,206,508 字节、约 1.2MB 的版本,此时距离 XP 发布已经接近十年。
兼容性也影响了 XP 的其他决策。在 XP SP2 中,微软将 32 位 Windows 的内存上限设为 4GB,以避免有缺陷的驱动程序导致崩溃;而 Windows 至今仍保留着文件系统隧道等特性,因为旧软件需要它们。
Windows XP 将于本月晚些时候迎来 25 周年,人们仍像庆祝国宝一样纪念 Bliss 壁纸。讽刺的是,那些为 XP 赢得良好声誉的应用中,有些编写得很糟糕,有些则只是检查了错误的版本号。
Windows XP Bliss 壁纸 4K当然,我们根本不需要知道这些。我们双击程序,它就打开了。
所以,下次有人说 XP 写得非常好、什么软件都能运行时,你就会知道这背后的真实故事了。