Windows 为什么有 System32 又有 SysWOW64?因为名字叫 32 的文件夹里装的全是 64 位文件

封面,又小又旧的文件夹塞满崭新的大零件,又大又新的文件夹只剩几个老古董

前几天聊完 Linux 那个两块 1.5MB 硬盘搞出两个 bin 目录的事,有朋友在后台留言问我。

他说,既然 Unix 这边为了历史包袱打补丁,那 Windows 这边呢?

Windows 系统盘里那个 System32,还有名字奇奇怪怪的 SysWOW64,到底又是怎么回事?

说真的,如果你觉得 Linux 祖师爷的操作算草台,那 Windows 这边的故事,能直接把你的常识按在地上反复摩擦。

你打开任何一台今天常用的 Windows 电脑,点进 C:\Windows 目录。

你一定能看到两个核心文件夹,一个叫 System32,另一个叫 SysWOW64

旁边可能还孤零零躺着一个积满灰尘的老古董,叫 System

按正常人类的直觉去猜,小学生都能给出答案。

System32 肯定放的是 32 位系统文件,SysWOW64 肯定放的是 64 位系统文件。

对吧?合情合理,童叟无欺。

但如果你拿着这个结论去问微软的系统工程师,对方大概率会露出一抹看破红尘的微笑。

然后告诉你一个反常识的真相。

在 64 位 Windows 系统里,System32 这个名字带 32 的文件夹,里面装的全是正儿八经的 64 位系统文件。

而那个名字带 64 的 SysWOW64,里面装的反而是 32 位的旧系统文件。

32 是 64,64 是 32。

第一次听说这事的人,基本都是满脸问号。

这不是开玩笑。

你现在就可以在自己电脑上随便找个查看 PE 文件头的工具,去翻一下这两个文件夹里的 cmd.exe 或者 notepad.exe

System32 底下的那个,架构写得清清楚楚,x86-64。

SysWOW64 底下的那个,架构同样写得清清楚楚,x86 32位。

两边的内容,完完全全颠倒过来了。

当年微软的架构师到底是怎么想的,才会搞出这么魔幻的设计?

这事还真不能全怪微软。

如果要给这口大锅找个责任人,得算在九十年代全世界所有写 Windows 程序的开发者头上。

在三十多年前的 Windows 3.1 时代,系统是 16 位的,核心文件都放在 C:\Windows\System 目录底下。

到了 1995 年前后,微软推出了 32 位的 Windows 95 和后来的 Windows NT。

为了把新的 32 位动态链接库和老的 16 位文件区分开,微软建了一个新文件夹,叫 System32

在当时,这个命名没有任何毛病。

System 是 16 位,System32 是 32 位,逻辑非常清晰。

问题出在接下来的十年里。

从九十年代中叶一直到两千年代初,个人电脑和桌面软件经历了一轮大爆发。

全世界成千上万的软件开发商、游戏公司、还有写安装包工具的程序员,在写代码的时候养成了一个偷懒的坏习惯。

大家不管三七二十一,直接把 C:\Windows\System32 这个绝对路径,硬编码写进了自己的代码和安装脚本里。

只要程序要调用一个系统 DLL,代码里直接写死这串路径。

到了 2005 年前后,64 位 CPU 普及了,微软开始做 64 位 Windows。

这时候微软的架构师们开会,发现自己被逼到了墙角。

如果按正常逻辑新建一个叫 System64 的文件夹放 64 位组件,原来的 System32 留给 32 位程序。

那全世界现存的所有 32 位软件源码,在重新编译成 64 位版本的时候,代码里所有硬编码了 System32 的地方,全部得人工找出来改成 System64

只要漏掉一个地方,程序编译出来跑到客户电脑上,当场报找不到动态库,直接崩溃。

而且当时很多第三方闭源库,开发者连源码都丢了,根本没法改。

面对全世界这片硬编码的汪洋大海,微软工程师选了一个极其骚气、但也极其管用的方案。

既然大家都把 System32 当成系统默认的核心目录,那我们就顺水推舟。

在 64 位系统里,把所有原生的 64 位系统文件,直接塞进 System32 里。

这样所有重新编译的 64 位程序,代码里的 System32 一个字都不用改,直接就能找到自己需要的 64 位库。

那原来的那些旧 32 位程序怎么办呢?

微软专门开辟了一个新文件夹,放 32 位的兼容文件。

这个文件夹的全称叫 Windows 32-bit on Windows 64-bit,缩写一下,就成了 SysWOW64

它的意思是「运行在 64 位系统上的 32 位兼容环境」。

但光改名字还不够。

那些古老的 32 位软件运行起来的时候,可不知道有 SysWOW64 这回事,它们依然在头铁地疯狂访问 C:\Windows\System32

如果真让它们进 System32,拿到的是 64 位的 DLL。32 位的程序去加载 64 位的库,内存寻址当场就崩了。

为了解决这个问题,微软做了一套惊天动地的障眼法。

行业里管这个叫「文件系统重定向」。

从 Windows XP 64位和 Windows Vista 开始,微软在内核的 64 位子系统里埋了一个钩子。

只要检测到一个运行中的进程是 32 位的老程序,当它试图去读取 C:\Windows\System32 目录时,Windows 内核在底层瞬间掉包。

内核神不知鬼不觉地把这个请求,悄悄重定向到 C:\Windows\SysWOW64 目录下。

32 位的程序以为自己一直在 System32 里快乐玩耍,拿到的全是自己能用的 32 位零件。

而 64 位的程序直接大大方方读 System32,拿到的全是 64 位零件。

大家都有光明的未来。

只有微软负责维护操作系统底层的工程师,把这套重定向规则维护得头发掉光。

前几天聊 Linux 的时候,我们看到肯·汤普逊当年因为一块 1.5MB 磁盘满了,随手在 /usr 底下建了个 bin,结果后来的开发者为此吵了五十年,最后各大发行版又用软链接合二为一。

而 Windows 这边走的是完全相反、但也同样离谱的另一条路。

它为了给全世界程序员二十年间写下的偷懒硬编码擦屁股,硬生生把 64 位的灵魂塞进了名字叫 32 的躯壳里。

再搞了一个名字叫 64 的文件夹来装 32 位的零件。

最后在操作系统内核里装了一个隐形的传送门,天天负责在底层偷偷掉包。

整个计算机工业发展了这么多年,很多看似神秘高深的系统设计,只要往底层扒开看一眼。

里面其实全是一群绝顶聪明的人,在替另一群偷懒的人,小心翼翼地收拾烂摊子。

下回你在 C:\Windows 里看见这两个文件夹的时候,别再纠结自己的数学是不是学反了。

署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)
位旅人路过 次翻阅 初次见面