有人求助说一台 Windows 虚拟机坏了,启动不了。我去一看,黑屏白字,说,missing C:\Windows\System32\l_intl.nls,要我用 Windows 启动盘里的故障修复台修复。
怎么修复呢?没有说。我手边一时没有启动盘,自作聪明地把坏掉的虚拟机的硬盘文件 vhd 挂载到另一台虚拟机下做第二硬盘,查看 \Windows\System32\l_intl.nls 还在不在。在另一台虚拟机下看这硬盘挺健康的,\Windows\System32\l_intl.nls 也在。
我仍是复制了一份 l_intl.nls 给它,还是启动不了。
还是 Google 来一个办法,去取来 Windows 启动盘,在故障修复台命令行执行
chkdsk c: /r
30G 的硬盘,花了 1个多小时修理完毕,没提示有什么磁盘错误。重启,非常遗憾,仍是黑屏。
接着又试着把坏掉的虚拟机的硬盘文件 vhd 挂到另一台虚拟机下,直接在它的 Windows DOS 里执行
chkdsk c: /f
这跟故障修复台环境不同,chkdsk 能接受的参数也不同。这次修理快了很多,提示了一堆 Index 错误,看不懂,也不知修复了没有,看重启,仍是黑屏。
之后又尝试种种工具,无一有效。直到看到一个论坛的角落里(因为我花了几小时才看到,所以是角落)有人说,”YET ANOTHER Microsoft screw up”。一语惊醒梦中人!
那人建议试试 BIOS 重置、测试下内存(换下有问题的内存条)。我的是虚拟机,没有 BIOS 重置一说。我就新建了一个虚拟机,加载既有的 vhd,mamma mia,重见 Windows 的徽标在飘扬,舒了口气。
但是,我高兴得太早了,我很快发现此 Windows 非彼 Windows——我忘了这是虚拟机。刚才新建的虚拟机,加载的 vhd 文件,是有问题的虚拟机下的硬盘的最初状态!最初状态非常健康。这也是之前种种努力,把它挂载到其他虚拟机下尝试修复,修复时没发现问题,l_intl.nls 文件也在,而在有问题的虚拟机下真正加载的不单是这个 vhd,而是一个 Current State。修来修去,修的都不是 Current State。
明白这个道理之后,剩下的事情就很简单了。
我赶紧把 Current State 生成一个独立的 vhd 文件。在有问题的虚拟机的目录里,找到 [虚拟机名].vbox 来查看一下,从中找到 Current State 对应的文件名,我的是 {991f2a80-9fbe-48b5-9c02-27f745bdf81c}.vhd。这个 vhd 不是独立的,它是从最初状态,经过一次次 Snapshot (如果有的话),diff 得到的 Current State。
怎么把这些 diff 合并得到一个独立的 vhd 文件?VirtualBox 有个简单的命令:
VBoxManage clonehd \{991f2a80-9fbe-48b5-9c02-27f745bdf81c\}.vhd currentstate.vhd -format VHD
这命令必须在原 host machine 上运行,否则哪里去找 {991f2a80-9fbe-48b5-9c02-27f745bdf81c}.vhd 的 parent,parent 的 parent…
这次做的 currentstate.vhd,再次挂载到其他虚拟机里作第二硬盘,一看,果然,\Windows\System32\l_intl.nls is missing,赶紧,复制一个给它。
然后以 currentstate.vhd 为第一硬盘,加载到坏掉的虚拟机里,终于又见 Windows 的徽标在飘扬——这一次是真的真的真的 Windows!