几经波折,终于把这个大难题给解决了。
一直以来,有不少人为了实现多个Win7安装在单个盘里面,想出了很多方法。
其中最可行的一种就是用ImageX将多个Win7安装的install.wim合在一起,实现合盘的目的。
但是,这种方法的弊端在于,它依然要将Win7的整个安装包解压到某个盘的根目录,造成某个盘的文件非常杂乱,难看死了。
更大的弊端在于,因为它必须要将某些文件放在根目录,如果以后要在该盘放入新的系统,而碰巧这些系统的目录名跟Win7的相同,那就悲剧了。
其实,解决Win7合盘的关键之处在于,如何将Win7的安装目录放在一些自定义的子目录,同时Win7在安装时能自动搜索这个目录进行安装。
为了解决这个问题,我们来看一下Win7的iso包是怎么安装的。
一、插入Win7光盘后,BIOS将引导交给bootmgr
二、bootmgr会搜索当前光盘下boot文件夹的bcd,加载启动菜单,并选择唯一的一项启动
三、bootmgr启动Win7的安装PE,该安装PE运行当前光盘的sources文件夹下面的setup.exe程序进行安装
因为代码已经写死了,所以要修改里面引导目录实在是十分困难。
(都怪死微软封闭,如果像Linux那样,就可以改一下源代码就OK了。)
我们安装以上三步来分别破解,使得运行在D:\7600\下的Win7安装目录可以启动起来。
注意,D:\7600里面装的是Win7的iso包解压的文件,包括有boot,efi,sources等文件夹和文件。本文只提供大致思路,请见谅。
一、因为bootmgr在D:\7600,所以用普通的bootsect已经不可以引导起来,因为bootsect编写的mbr扇区只会运行根目录下面的bootmgr,这跟我们想的不一样,我们不采取bootsect写引导。我推荐用syslinux引导bootmgr,当然有人说用grub4dos也可以,但是我用grub4dos0.4.5死活启动不了。只需要在syslinux.cfg中加入以下的启动选项
MENU Win7 Install
KERNEL chain.c32
APPEND hd0,2 ntldr=/7600/bootmgr
二、修改bootmgr,让他不去boot文件夹找bcd,而是到/7600/boot目录找bcd,这里就比较困难,还好有前人已经做了这项工作,在我的博客里面的"修改bootmgr"有介绍,
直接对照着修改就好了。
三、修改bcd,bcd默认是到\sources\boot.wim文件夹来运行Win7的安装PE,我们要修改它,让它到\7600\sources\boot.wim中启动PE,这个比较简单,我们只需要用Win7自带的bcdedit就可以修改了,这个有很多教程,就不说了。
四、修改boot.wim,boot.wim是Win7的安装PE,默认只到各个分区的根目录寻找有没有合适的安装程序,并不会到子目录去寻找。这个就很麻烦了,因为我怎么知道它的程序是写在哪个文件,该修改哪个文件。经过几日思索,我想出了两个办法,
1、boot.wim的实质是PE,我们可以从里面装一个虚拟光驱,使它自动运行,并且把win7的iso虚拟做光驱就可以了。这个比较麻烦,而且不同的Win7PE,所需要的虚拟光驱的版本号不一样,这将是很麻烦。
2、boot.wim的实质是PE,其启动时可以设置运行我们的D:\7600\sources\setup.exe就可以实现自动运行了。问题是,怎么让PE在进入时就运行这个文件,首先,我们用dism挂载boot.wim,然后在挂载目录\Windows\System32下面建立一个文件,为winpeshl.ini,写入以下信息
[LaunchApps]
X:\boot.cmd
然后,我们在挂载目录的根目录中新建一个文件,写入数据为。
D:\7600\sources\setup.exe
然后,卸载boot.wim,将新的boot.wim覆盖掉原来的那个boot.wim,就可以了。
这时候,开机,就会发现,自动进入WIn7安装,再也不需要到命令行输入什么setup.exe了。并且,因为Win7是安装在子目录的,所以我们可以很方便地进行多个WIn7合盘,甚至是Win7与其它任意的操作系统合盘了。
以上就这么完了。我顺便在这里留个文件,看看谁明白里面究竟写点什么先。。
@echo off
setlocal EnableDelayedExpansion
set time=1
:begin
set cur=1
set cur2=123
echo 第!time!次搜索
set /A time=!time!+1
for %%i in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
set cur2=%%i
set cur=!cur2!:\pefishpeReadMe.txt
if exist !cur! (
goto end
)
)
goto begin
:end
echo !cur2!:\mm\sources\setup.exe
!cur2!:\mm\sources\setup.exe