无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
查看: 471|回复: 29
打印 上一主题 下一主题

[原创] 在VHD系统下,实现每次重启都还原到最佳初始状态的完美方案

[复制链接]
跳转到指定楼层
1#
本帖最后由 D_M_GuYing 于 2025-10-11 15:05 编辑

调整了操作顺序:先完成差分文件的创建,确认成功后再修改启动引导配置。这样可以避免在差分文件创建失败的情况下错误修改引导配置

前题:你要做好了VHD系统到最佳状态,到PE创建了差分,修改启动项用差分启动系统。例如:
父文件:D:\SYS\25H2.VHDX
差分文件:D:\SYS\A.VHDX





执行后,会自动搜索.CMD文件夹下A.VHDX和B.VHDX执行删除操作,如果你的启动项是A.VHDX,因为正在使用中,所以是删除不掉的。然后.CMD建立一个新的差分文件B.VHDX,修改启动项的设备文件为B.VHDX,反之亦然。

就这吗简单!


复制代码,另存为.CMD,放到你的VHDX所在文件夹,修改你的变量
:: 差分子文件变量
set "VHD1=A.vhdx"
set "VHD2=B.vhdx"
:: 父文件变量
set "BASE_VHD=25H2.VHDX"

可删除最后的那个暂停代码pause,创建计划任务,每次系统启动时,执行.cmd。这样就不会每次手动了。--------------------------------------------------------------------------------------------------------------------------------------


@echo off
chcp 65001 >nul 2>&1
setlocal enabledelayedexpansion
cls


:: 差分子文件变量
set "VHD1=A.vhdx"
set "VHD2=B.vhdx"
:: 父文件变量
set "BASE_VHD=25H2.VHDX"  


:: 强制删除A.vhdx和B.vhdx(无论是否存在)
echo 正在清理旧文件...
if exist "!VHD1!" (
    del /f /q "!VHD1!" >nul 2>&1
    if not exist "!VHD1!" (echo ✅ 已删除 !VHD1!) else (echo ⚠️ 无法删除 !VHD1!,可能被占用)
)
if exist "!VHD2!" (
    del /f /q "!VHD2!" >nul 2>&1
    if not exist "!VHD2!" (echo ✅ 已删除 !VHD2!) else (echo ⚠️ 无法删除 !VHD2!,可能被占用)
)
echo.


:: 1. 获取当前目录
pushd %~dp0 & cd /d "%~dp0"
set "CUR_DIR=%cd%"
echo Current folder: %CUR_DIR%
echo VHD files to switch: %VHD1% ↔ %VHD2%


:: 2. 提取盘符和路径
set "DRIVE=%CUR_DIR:~0,2%"
set "REL_PATH=%CUR_DIR:~2%"


:: 3. 自动搜索VHD启动项ID
echo.
echo 正在自动搜索VHD启动项ID...
set "VHDX_ID="
set "in_vhd_entry=0"


:: 遍历bcdedit输出,提取包含"vhd"的启动项ID
for /f "tokens=1,* delims=:" %%a in ('bcdedit /enum /v 2^>nul') do (
    :: 清理行首空格和特殊字符
    set "line=%%a%%b"
    set "line=!line: =!"
   
    :: 检测到标识符行,提取ID
    if "!line:~0,10!"=="identifier" (
        set "current_id=!line:identifier=!"
        set "current_id=!current_id:{=!"  :: 移除左大括号
        set "current_id=!current_id:}=!"  :: 移除右大括号
        set "current_id=!current_id:"=!"  :: 移除引号
        set "in_vhd_entry=0"  :: 重置标记
    )
   
    :: 检测到包含"vhd"的行,标记为VHD启动项
    echo "!line!" | findstr /i "vhd" >nul 2>&1
    if !errorlevel! equ 0 (
        set "in_vhd_entry=1"
    )
   
    :: 若在VHD启动项中且已获取ID,则确定为目标ID
    if !in_vhd_entry! equ 1 if defined current_id (
        set "VHDX_ID={!current_id!}"
        goto :found_vhd_id  :: 找到后退出循环
    )
)
:found_vhd_id


:: 验证ID是否存在
if "!VHDX_ID!"=="" (
    echo ❌ 错误:未找到VHD类型的启动项,请检查系统配置
    pause
    exit /b 1
)
echo ✅ 找到VHD启动项ID:!VHDX_ID!


:: 4. 构建路径
set "SUFFIX_DEVICE=,locate=custom:12000002"
set "SUFFIX_OSDEVICE=,locate=custom:22000002"
set "VHD1_DEV=vhd=[%DRIVE%]%REL_PATH%\%VHD1%%SUFFIX_DEVICE%"
set "VHD1_OS=vhd=[%DRIVE%]%REL_PATH%\%VHD1%%SUFFIX_OSDEVICE%"
set "VHD2_DEV=vhd=[%DRIVE%]%REL_PATH%\%VHD2%%SUFFIX_DEVICE%"
set "VHD2_OS=vhd=[%DRIVE%]%REL_PATH%\%VHD2%%SUFFIX_OSDEVICE%"


:: 5. 检测文件存在性(清理后应该都不存在)
set "VHD1_EXIST=0"
set "VHD2_EXIST=0"
if exist "%CUR_DIR%\%VHD1%" set "VHD1_EXIST=1"
if exist "%CUR_DIR%\%VHD2%" set "VHD2_EXIST=1"


:: 6. 显示检测结果
echo.
echo ==============================================
echo  File Detection:
if %VHD1_EXIST% equ 1 (echo ✅ %VHD1% exists) else (echo ❌ %VHD1% not found)
if %VHD2_EXIST% equ 1 (echo ✅ %VHD2% exists) else (echo ❌ %VHD2% not found)
echo ==============================================


:: 7. 确定目标差分文件
set "TARGET="
set "NEW_DEV="
set "NEW_OS="


if %VHD1_EXIST% equ 1 (
    set "TARGET=%VHD2%"
    set "NEW_DEV=%VHD2_DEV%"
    set "NEW_OS=%VHD2_OS%"
) else if %VHD2_EXIST% equ 1 (
    set "TARGET=%VHD1%"
    set "NEW_DEV=%VHD1_DEV%"
    set "NEW_OS=%VHD1_OS%"
) else (
    :: 当A和B都不存在时,默认使用A.vhdx
    set "TARGET=%VHD1%"
    set "NEW_DEV=%VHD1_DEV%"
    set "NEW_OS=%VHD1_OS%"
    echo 提示:所有文件均不存在,默认切换目标为 %TARGET%
)


:: 8. 先执行差分文件创建任务
echo.
echo ==============================================
echo 子文件创建任务:
echo  母文件:%BASE_VHD%
echo  子文件:%TARGET%(与启动目标一致)
echo  目标路径:%CUR_DIR%
echo ==============================================


set "CREATE_SUCCESS=0"
:: 检查母文件是否存在
if not exist "%CUR_DIR%\%BASE_VHD%" (
    echo ❌ 错误:母文件 %BASE_VHD% 未在 %CUR_DIR% 找到,无法创建子文件
) else (
    echo ⚠️  正在创建差分文件(需管理员权限)...
    (
        echo create vdisk file="%CUR_DIR%\%TARGET%" parent="%CUR_DIR%\%BASE_VHD%"
        echo exit
    ) | diskpart
   
    :: 验证差分文件创建结果
    if exist "%CUR_DIR%\%TARGET%" (
        echo ✅ 成功:差分文件 %TARGET% 已创建 → %CUR_DIR%\%TARGET%
        set "CREATE_SUCCESS=1"
    ) else (
        echo ❌ 失败:差分文件未创建,请检查权限和母文件完整性
    )
)
echo ==============================================


:: 9. 只有差分文件创建成功后,才执行引导切换
if %CREATE_SUCCESS% equ 1 (
    echo.
    echo Auto-switching to %TARGET%...
    bcdedit /enum %VHDX_ID% >nul 2>&1
    timeout /t 1 /nobreak >nul


    bcdedit /set %VHDX_ID% device "%NEW_DEV%" >nul
    bcdedit /set %VHDX_ID% osdevice "%NEW_OS%" >nul
    bcdedit /enum %VHDX_ID% >nul 2>&1
    timeout /t 1 /nobreak >nul


    :: 验证引导切换结果
    set "FINAL_DEV="
    for /f "tokens=2,*" %%a in ('bcdedit /enum %VHDX_ID% /v ^| findstr /i "device "') do set "FINAL_DEV=%%b"


    echo.
    echo ==============================================
    echo Switch Completed! Target: %CUR_DIR%\%TARGET%
    echo Final Path: %FINAL_DEV%
    echo ==============================================
    if "%FINAL_DEV%"=="%NEW_DEV%" (
        echo ✅ Success: Path is correct
    ) else (
        echo ⚠️  Success: Actual path set to %NEW_DEV%
    )
) else (
    echo.
    echo ⚠️  差分文件创建失败,未修改启动引导配置
)


echo.
echo 按任意键退出...
set /p=
endlocal


评分

参与人数 2无忧币 +10 收起 理由
d9o + 5 赞一个!
lemonle79 + 5 很给力!

查看全部评分

2#
发表于 7 小时前 | 只看该作者
好办法
回复

使用道具 举报

3#
发表于 6 小时前 | 只看该作者
学习了 谢谢
回复

使用道具 举报

4#
发表于 6 小时前 | 只看该作者
这办法还是可以的
回复

使用道具 举报

5#
发表于 6 小时前 | 只看该作者
好思路 支持

点评

这话说到我心里了,就是抛砖引玉,只是提供个想法  详情 回复 发表于 半小时前
回复

使用道具 举报

6#
发表于 5 小时前 | 只看该作者
学习一下!
回复

使用道具 举报

7#
 楼主| 发表于 5 小时前 | 只看该作者
#在这里快调整了操作顺序:先完成差分文件的创建,确认成功后再修改启动引导配置。这样可以避免在差分文件创建失败的情况下错误修改引导配置速回复#
回复

使用道具 举报

8#
发表于 5 小时前 | 只看该作者
对于vhd差分还原,坛里几年前就在讨论,思路都大差不差。
比较完整的成品是 dos时代菜鸟发布的 http删://bbs删.wuyou.net/forum.php?mod=viewthread&tid=429415
支持vhd文件在无盘符分区的场景(涉及NT设备路径),其用了一段我看不懂的pecmd脚本来实现NT设备路径的转换。
我用AI写了个CPP命令行程序来实现转换,用在我的精简版系统中。

点评

看了你的离线删除APPs,我也搞过一个,分享切磋一下哈,把加载的去镜像文件夹扡到.CMD就行@echo off pushd %~dp0 & cd /d "%~dp0" if "%1"=="" EXIT powershell -Command "$mountPath='%1'; $targetApps=@('Win  详情 回复 发表于 4 小时前
时代菜鸟的这个我拜读过,他的功力要比我深厚的多,我们出发点虽然一样,但我主打的是人性化简单化把这个.cmd扔到你要的文件夹里再把变量改成自己的就一切OK  详情 回复 发表于 5 小时前
回复

使用道具 举报

9#
 楼主| 发表于 5 小时前 | 只看该作者
hlowld 发表于 2025-10-11 15:19
对于vhd差分还原,坛里几年前就在讨论,思路都大差不差。
比较完整的成品是 dos时代菜鸟发布的 http删://b ...

时代菜鸟的这个我拜读过,他的功力要比我深厚的多,我们出发点虽然一样,但我主打的是人性化简单化把这个.cmd扔到你要的文件夹里再把变量改成自己的就一切OK
回复

使用道具 举报

10#
 楼主| 发表于 4 小时前 | 只看该作者
hlowld 发表于 2025-10-11 15:19
对于vhd差分还原,坛里几年前就在讨论,思路都大差不差。
比较完整的成品是 dos时代菜鸟发布的 http删://b ...

看了你的离线删除APPs,我也搞过一个,分享切磋一下哈,把加载的去镜像文件夹扡到.CMD就行@echo off
pushd %~dp0 & cd /d "%~dp0"
if "%1"=="" EXIT

powershell -Command "$mountPath='%1'; $targetApps=@('WindowsSoundRecorder','Paint','BingWeather','WindowsCamera','zune','News','Xbox','Solitaire','Clipchamp','StickyNotes','ToDo','FeedbackHub','GetHelp','QuickAssist','PowerAutomate','Office','DevHome'); $allPackages=Get-AppxProvisionedPackage -Path $mountPath; foreach($app in $targetApps){$packagesToRemove=$allPackages | Where-Object { $_.PackageName -match $app }; if($packagesToRemove){Write-Host \"`n发现匹配 '$app' 的应用,开始删除:\" -ForegroundColor Cyan; foreach($pkg in $packagesToRemove){Write-Host \"删除:$($pkg.PackageName)\" -ForegroundColor Yellow; Remove-AppxProvisionedPackage -Path $mountPath -PackageName $pkg.PackageName -ErrorAction SilentlyContinue}}else{Write-Host \"未找到匹配 '$app' 的应用\" -ForegroundColor Gray}}; Write-Host \"`n批量删除操作完成!\" -ForegroundColor Green"
pause


回复

使用道具 举报

11#
发表于 4 小时前 | 只看该作者
感谢分享!
回复

使用道具 举报

12#
发表于 2 小时前 | 只看该作者
楼主能把你的批处理上传吗?你贴出来的批处理,有部份变成表情了。

点评

惭愧呀,上传不是没成功,.txt,.7z都试了,附件不上去,你说的表情是❌ ⚠️✅?那是有意为之的不是乱码  详情 回复 发表于 15 分钟前
回复

使用道具 举报

13#
发表于 2 小时前 | 只看该作者
学习学习,感谢分享
回复

使用道具 举报

14#
发表于 1 小时前 | 只看该作者
厉害。收藏先
回复

使用道具 举报

15#
发表于 1 小时前 | 只看该作者
谢谢楼主分享
回复

使用道具 举报

16#
发表于 1 小时前 | 只看该作者
谢谢分享!
回复

使用道具 举报

17#
发表于 半小时前 来自手机 | 只看该作者
固定bcd guid就不需每次创建,切换就可

点评

全球都用同一id不会冲突,差分只需创建一次,后续ab都用拷贝,比diskpart快,,,快几毫秒?你拷贝的那个正在使用,你怎么拷贝?你拷贝的那个没了呢,你拷贝的那个损坏了,跟父文件不相联呢?从父文件直接重建差分才  详情 回复 发表于 19 分钟前
你的固定了,别人呢?  详情 回复 发表于 半小时前
回复

使用道具 举报

18#
发表于 半小时前 | 只看该作者
学习一下
回复

使用道具 举报

19#
 楼主| 发表于 半小时前 | 只看该作者

这话说到我心里了,就是抛砖引玉,只是提供个想法
回复

使用道具 举报

20#
 楼主| 发表于 半小时前 | 只看该作者
szwp 发表于 2025-10-11 19:46
固定bcd guid就不需每次创建,切换就可

你的固定了,别人呢?

点评

全球都用同一id不会冲突,差分只需创建一次,后续ab都用拷贝,比diskpart快  详情 回复 发表于 半小时前
回复

使用道具 举报

21#
发表于 半小时前 来自手机 | 只看该作者
D_M_GuYing 发表于 2025-10-11 20:00
你的固定了,别人呢?

全球都用同一id不会冲突,差分只需创建一次,后续ab都用拷贝,比diskpart快

点评

差分只需创建一次,如果你没有备份,启动后就已经变了,还不是要回到重建到一步  详情 回复 发表于 24 分钟前
按实际 ,你说的没错,按严谨,那就顺着来总是没错的,排除一切外在因素的影响,那样不好吗,你就没有过重建立新VHDX重装系统的时候吗,那时,ID是不是变了,,你行,那你弄个通用的出来我学习下好不  详情 回复 发表于 27 分钟前
回复

使用道具 举报

22#
发表于 半小时前 来自手机 | 只看该作者
初始化时创建ida idb项和差分,以后只需copy成功即设置默认
回复

使用道具 举报

23#
 楼主| 发表于 27 分钟前 | 只看该作者
szwp 发表于 2025-10-11 20:05
全球都用同一id不会冲突,差分只需创建一次,后续ab都用拷贝,比diskpart快

按实际 ,你说的没错,按严谨,那就顺着来总是没错的,排除一切外在因素的影响,那样不好吗,你就没有过重建立新VHDX重装系统的时候吗,那时,ID是不是变了,,你行,那你弄个通用的出来我学习下好不
回复

使用道具 举报

24#
 楼主| 发表于 24 分钟前 | 只看该作者
szwp 发表于 2025-10-11 20:05
全球都用同一id不会冲突,差分只需创建一次,后续ab都用拷贝,比diskpart快

差分只需创建一次,如果你没有备份,启动后就已经变了,还不是要回到重建到一步
回复

使用道具 举报

25#
发表于 21 分钟前 来自手机 | 只看该作者
俺的id不管是legay还是uefi都是相同,切换启动用的相同id,现在手机不方便多打,可以创建一个全A的guid给a.vhdx 全B的guid给B.vhdx

点评

俺的,俺的,,你以为别人都是俺的?你以为你家ID就不会变了?你以为别人都会自己找ID再复制进去吗?自动重找,找到建立,会排除很多不确定的,这样不好吗,我可以接受不同的声音,但你这种声音太自我弱智,我不接受  详情 回复 发表于 8 分钟前
回复

使用道具 举报

26#
 楼主| 发表于 19 分钟前 | 只看该作者
szwp 发表于 2025-10-11 19:46
固定bcd guid就不需每次创建,切换就可

全球都用同一id不会冲突,差分只需创建一次,后续ab都用拷贝,比diskpart快,,,快几毫秒?你拷贝的那个正在使用,你怎么拷贝?你拷贝的那个没了呢,你拷贝的那个损坏了,跟父文件不相联呢?从父文件直接重建差分才是正途
回复

使用道具 举报

27#
 楼主| 发表于 15 分钟前 | 只看该作者
1801403 发表于 2025-10-11 18:08
楼主能把你的批处理上传吗?你贴出来的批处理,有部份变成表情了。

惭愧呀,上传不是没成功,.txt,.7z都试了,附件不上去,你说的表情是❌ ⚠️✅?那是有意为之的不是乱码
回复

使用道具 举报

28#
发表于 13 分钟前 来自手机 | 只看该作者
没有绝对的可靠,不能保证系统一定会有diskpart和父损坏情况
回复

使用道具 举报

29#
 楼主| 发表于 8 分钟前 | 只看该作者
szwp 发表于 2025-10-11 20:17
俺的id不管是legay还是uefi都是相同,切换启动用的相同id,现在手机不方便多打,可以创建一个全A的guid给a. ...

俺的,俺的,,你以为别人都是俺的?你以为你家ID就不会变了?你以为别人都会自己找ID再复制进去吗?自动重找,找到建立,会排除很多不确定的,这样不好吗,我可以接受不同的声音,但你这种声音太自我弱智,我不接受
回复

使用道具 举报

30#
发表于 1 分钟前 | 只看该作者
现在很少用VHD了,因为象snapshot这样的恢复软件极快,一点就恢复了,所以懒得搞其它的了,

象虚拟机更不用了,因为如与硬件相关就不行了,不过移动硬盘上的WTG还是用VHD的,有他的好处,

不过还是要支持的,各种方案下总有进步,总会有更适用的选择,

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2025-10-11 20:39

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表