
前几天聊完 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 里看见这两个文件夹的时候,别再纠结自己的数学是不是学反了。