dos时代菜鸟 发表于 2021-1-14 07:10:08

527104427 发表于 2021-1-14 00:15
ENVI ?&Buf=FVAR,BootOrder
FIND *&Buf=, MESS BIOS! MESS UEFI



多谢

dos时代菜鸟 发表于 2021-1-14 07:11:44

CodeHz 发表于 2021-1-14 00:06
你是不是跑在不同的特权级别,看你标题一个管理员一个不是
这玩意挺复杂的,有全局的挂载,和会话的挂载 ...

哈哈,又学到些东西,
关于系统管理权,我一直都是开的管理员账户的,所以CMD 默认也是管理员运行。

liuzhaoyzz 发表于 2021-1-14 07:38:20

dos时代菜鸟 发表于 2021-1-13 20:59
这个 全 依赖 Diskpart+注册表 ,按理说 diskpart 的硬盘和分区序列应该 和 注册表中 记载的是一致的。
...

这个版本的结果还是不对,电脑里面有两个MBR硬盘,一个GPT硬盘,从MBR硬盘激活的FAT32分区启动,结果定位到了GPT硬盘的ESP分区了。

liuzhaoyzz 发表于 2021-1-14 07:40:24

dos时代菜鸟 发表于 2021-1-13 20:59
这个 全 依赖 Diskpart+注册表 ,按理说 diskpart 的硬盘和分区序列应该 和 注册表中 记载的是一致的。
...

这个版本的结果还是不对,电脑里面有两个MBR硬盘,一个GPT硬盘,从MBR硬盘激活的FAT32分区启动,结果定位到了GPT硬盘的ESP分区了。

liuzhaoyzz 发表于 2021-1-14 07:41:53

CodeHz 发表于 2021-1-14 00:06
你是不是跑在不同的特权级别,看你标题一个管理员一个不是
这玩意挺复杂的,有全局的挂载,和会话的挂载 ...

看了这个技术原理分析,真的是大吃一惊,后台做了那么多尝试和技术分析,真复杂!

dos时代菜鸟 发表于 2021-1-14 08:20:28

liuzhaoyzz 发表于 2021-1-14 07:40
这个版本的结果还是不对,电脑里面有两个MBR硬盘,一个GPT硬盘,从MBR硬盘激活的FAT32分区启动,结果定位 ...

这个 是 根据注册表 信息来的,
看这个
reg query HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control /v FirmwareBootDevice
难道不准确?
还是 diskpart 与这个 不一致?

看来 真要用api 了,注册表 靠不住。

liuzhaoyzz 发表于 2021-1-14 08:23:46

dos时代菜鸟 发表于 2021-1-14 08:20
这个 是 根据注册表 信息来的,
看这个
reg query HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control...

      之前CodeHz大神已经发帖说明了啊,注册表靠不住,你看他的回帖。

dos时代菜鸟 发表于 2021-1-14 08:34:41

liuzhaoyzz 发表于 2021-1-14 08:23
之前CodeHz大神已经发帖说明了啊,注册表靠不住,你看他的回帖。

是呀,是呀,还是要用到 aip 获取才保险

窄口牛 发表于 2021-1-14 08:44:31

注册表肯定靠不住,你们的那些项,我这儿根本就没有。

dos时代菜鸟 发表于 2021-1-14 09:58:30

本帖最后由 dos时代菜鸟 于 2021-1-14 11:35 编辑

不知道 bcdedit /enum {bootmgr} 获取的靠谱不



diskpart 获取不到,就用 bcdedit 找一下。
这个在pe 下 和 win 下 我这边都 通过了。还有其他特殊引导方式的 win可能需要测试下。至于 pe 不敢奢望太多。


如果 特定分区 有盘符,就询问是否卸载,如果没有盘符,就询问是否挂载。

同时考虑 中英文环境,做了关键词对比专用 代码。
不知道 这个 效果怎么样。 要不是 pecmd 会被 报毒,也不考虑用 纯 cmd 脚本。




dos时代菜鸟 发表于 2021-1-14 11:57:23

liuzhaoyzz 发表于 2021-1-13 07:38
用这个版本,我在英文版win7下面测试,结果不对。
英文版win7,为了正常显示中文目录,国家我选择了中国 ...

新改进了一下,应该能 解决这个问题。

liuzhaoyzz 发表于 2021-1-14 12:36:05

本帖最后由 liuzhaoyzz 于 2021-1-14 12:37 编辑

dos时代菜鸟 发表于 2021-1-14 09:58
不知道 bcdedit /enum {bootmgr} 获取的靠谱不



结果还是不对,从FAT32分区启动,本来有盘符是H,结果提示挂载到了Z盘,资源管理器里面看不到Z盘,回车继续之后,能看到Z盘,跟H盘是同一个。

bcdedit还容易出问题。

dos时代菜鸟 发表于 2021-1-14 12:58:32

本帖最后由 dos时代菜鸟 于 2021-1-14 15:59 编辑

liuzhaoyzz 发表于 2021-1-14 12:36
结果还是不对,从FAT32分区启动,本来有盘符是H,结果提示挂载到了Z盘,资源管理器里面看不到Z盘,回车继 ...
这个说明是成功的,脚本需要改进下。
1.你的系统缺少 bcdedit ,这个可能是系统的事情。
2.diskpart 找到 目标卷,没有把 对应的 盘符 赋值,这个需要 脚本改进
如下:


@echo off
setlocal ENABLEDELAYEDEXPANSION
rem 通过diskpart获取 bcd 启动硬盘和分区,为其分配/卸载盘符。
rem 涉及命令 chcp diskpart bcdedit ,批处理指令 forif set exit echo call 等
rem 脚本中 call:XXXX 有一个 errorlevel 返回值,由 exit /b N 设定,如果 errorlevel=1 就说明该程序段 没有达到目的,如果 返回0 ,说明成功了。

call:init
if errorlevel 1 goto :end0

set x=Y
if not "!bcd_ltr!"=="" (
        set /p x=Will dismount Volume !bcd_vol! from !bcd_ltr!: , Are you sure^(Yes/No^)?___
        if /i "!x: =!" == "N" goto end0
        if /i "!x: =!" == "Y" call:load_script script_down
) else (
        set /p x=Will mount Volume !bcd_vol! to !ltrs:~-1!: , Are you sure^(Yes/No^)?___
        if /i "!x: =!" == "N" goto end0
        if /i "!x: =!" == "Y" call:load_script script_up
)
:end0

pause
if exist %tempfile% del %tempfile%
goto :eof




rem 初始化---初始化定义一些变量 并获取 bcd_vol ----------------
:init
        for %%c in ( chcp.com diskpart.exe bcdedit.exe)do (
                if not exist %windir%\system32\%%c (
                        echoComponents is not found : %%c !
                        exit /b 1
                )
        )
       
        for /f "tokens=2 delims=:" %%c in ('chcp') do (set page=%%c)
        for %%c in (936 437) do (if !page! equ %%c set page_code=ok)
        if not defined page_code (        echo Page_code Error! && exit /b 1)

        set "CN_str1=卷"
        set "CN_str2=系统"
       
        SET "EN_str1=Volume"
        set "EN_str2=System"

        set "分割线=-------------------------------------------------------------------------------------------"
        set tempfile="%temp%\%~n0.diskpart_script_temp"
        set Used_LTRs=,
       
        echo !分割线!
        call:bcdedit
        if errorlevel 1 (
                set bcdedit_error=1
                echo BCDedit did not find BCD_VOL!
        )
        >%tempfile%echo list vol
        for /f "delims=" %%c in ('diskpart /s %tempfile%') do (
                set l0=%%c && set "l0= !l0:~1!"
                for /f "tokens=1,2" %%h in ("!l0!") do (
                        CALL:STR_X str1 %%h
                        if not errorlevel 1 (
                                SET "ltr=!l0:~14,3!" && set "ltr=!ltr: =!" && set Used_LTRs=!used_ltrs!,!ltr!
                                set vol_ltr_s=!vol_ltr_s!%%i:!ltr!,
                                if defined bcd_vol (if /i "!bcd_vol!"=="%%i"   (set "l0=*!l0:~1!"                     ))
                                if defined bcd_ltr (if /i "!bcd_ltr!"=="!ltr!" (set "l0=*!l0:~1!" && set "bcd_vol=%%i"))
                                SET info=!l0:~-9!&& set info=!info: =!
                                if defined bcdedit_error (
                                        CALL:STR_X STR2 !info!
                                        if not errorlevel 1 (set "l0=*!l0:~1!" && set "BCD_VOL=%%i" && set "bcd_ltr=!ltr!" )
                                )
                                echo !l0!
                                if "%%i"=="###" echo !分割线!
                        )
                )
        )
        echo !分割线!
        if not defined bcd_vol (
                echo Can not find System_volume ... Error!
                exit /b 1
        )
        call:unltrs2
        rem set ltrs=Z
exit /b 0
:init_end
rem 执行某一脚本--并显示BCD_VOL信息---------------
:load_script
        call:%1
        for /f "delims=" %%h in ('diskpart /s %tempfile%') do (
                set "l0=%%h"
                for /f "tokens=1,2 delims= " %%r in ("!l0:~1!") do (
                        call:str_x str1 %%r
                        if not errorlevel 1 ( if /inot "%%s"=="###" (
                                SET "ltr=!l0:~14,3!" && set "ltr=!ltr: =!"&& set Used_LTRs=!used_ltrs!,!ltr!
                        ))
                        if "!l0:~0,1!"=="*" (
                                echo.
                                echo !分割线!
                                echo !l0!
                                echo !分割线!
                                set "bcd_ltr=!ltr!"
                        )
                )
        )
        call:unltrs2
        rem set ltrs=Z
exit /b 0
:load_script

rem diskpart_脚本-----------------------------------------------
:script0
        >%tempfile% echo sele vol !BCD_VOL!
exit /b
:script0_end

:script_up
        call:script0
        >>%tempfile% echo assign letter=!ltrs:~-1!
        >>%tempfile% echo list vol
exit /b
:script_up_end

:script_down
        call:script0
        >>%tempfile% echo remove
        >>%tempfile% echo list vol
exit /b
:script_down_end

rem 获取空余盘符-----------------------------------------------
:unltrs2
        set ltrs=
        set ltrs0=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
        for %%c in (!used_ltrs!) do (set "ltrs0=!ltrs0:%%c=!")
        for %%c in (!ltrs0!) do (if not exist %%c:\ set "ltrs=!ltrs!%%c")
exit /b
:unltrs2_end

rem 字符串对比-----------------------------------------------
:str_x
rem 两个变量,%1= str1 str2 str3 等 存储关键字的变量名,%2=数值
rem 分别判断中文、英文 的关键字变量内容 与 数值是否一致,如果一致,返回1,否则返回0
        for %%x in (CN EN) DO (        if /i "!%%x_%1!"=="%2" exit /b 0)
exit /b 1
:str_x_end

rem通过bcdedit 获取bcd 分区----------------
:bcdedit
set "str9=device"
for /f "tokens=1,2 delims= " %%c in ('bcdedit /enum {bootmgr}') do (
        if /i "%%c"=="!str9!" (
                set l0=%%d && set "l0=!l0: =!" && set "l0=!l0:volume=+!"
                if not "!l0:~-1!"==":" (               
                        for /f "tokens=2 delims=+" %%h in ("!l0!") do (
                                set "bcd_vol=%%h"
                                exit /b 0
                        )
                ) ELSE (
                        set "bcd_ltr=!l0:~-2,1!"
                        exit /b 0
                )
        )
)
exit /b 1
:bcdedit_end




提示 回车 才 挂载、卸载,而不是自动挂载,卸载,就是为了 以防万一的。如果输入了 x 就 退出了。




psp659 发表于 2021-1-14 14:08:21

问题很多都是闭源的,另外不知道他们的软件是否能够确定我在一楼所说的引导分区?

liuzhaoyzz 发表于 2021-1-14 16:41:00

dos时代菜鸟 发表于 2021-1-14 12:58
这个说明是成功的,脚本需要改进下。
1.你的系统缺少 bcdedit ,这个可能是系统的事情。
2.diskpart 找 ...

晚上回家试试看看

dos时代菜鸟 发表于 2021-1-14 16:47:42

liuzhaoyzz 发表于 2021-1-14 16:41
晚上回家试试看看

好的,辛苦

刚测试 u盘上启动pe ,检测的不准。
不知道用u盘启动 本地系统,会不会也不准。

liuzhaoyzz 发表于 2021-1-14 17:27:12

dos时代菜鸟 发表于 2021-1-14 16:47
好的,辛苦

刚测试 u盘上启动pe ,检测的不准。


      刚才测试了,从激活的FAT32分区UEFI启动,结果正确。从ESP分区UEFI启动,结果正确。
bootmgfw.efi→pe.wim结果是空值,这个场景很少,不是很紧要。

如果能够去掉确认,恢复原状最好,就是如果原来有盘符就维持原状;如果没有盘符就分配个盘符。

窄口牛 发表于 2021-1-14 19:12:08

有XP可用的bcdedit吗?

CodeHz 发表于 2021-1-14 19:46:41

窄口牛 发表于 2021-1-14 19:12
有XP可用的bcdedit吗?

按文档是没有的,,从 win7 开始提供

dos时代菜鸟 发表于 2021-1-14 21:07:52

单丛 diskpart 角度考量,XP下可以不用BCDEDIT,本贴题目是win 7.8.10 的本地系统。没考虑XP 和各类PE。

dos时代菜鸟 发表于 2021-1-14 21:10:10

liuzhaoyzz 发表于 2021-1-14 17:27
刚才测试了,从激活的FAT32分区UEFI启动,结果正确。从ESP分区UEFI启动,结果正确。
bootmgfw.e ...

这个倒是容易,明天改下吧,
可以改成,无则自动加载,有则询问是否卸载。

dos时代菜鸟 发表于 2021-1-14 21:12:12

u盘启动PE,我是用GEUB引导的非根目录下BOOTMGR。明天试试把BOOTMGR放根目录试试。

liuzhaoyzz 发表于 2021-1-14 21:24:41

dos时代菜鸟 发表于 2021-1-14 21:10
这个倒是容易,明天改下吧,
可以改成,无则自动加载,有则询问是否卸载。

别询问了,如有原来有盘符,就不用动原来的。如果没有就自动卸载原来的,维持原状,保持现场。

dos时代菜鸟 发表于 2021-1-14 22:11:32

liuzhaoyzz 发表于 2021-1-14 21:24
别询问了,如有原来有盘符,就不用动原来的。如果没有就自动卸载原来的,维持原状,保持现场。

你是说,
有盘符,就卸载,
没盘符,就加载?
这个可以做到。

没盘符,哪来的原来的盘符?
除非以前有,这就要在卸载的时候找个地方记录下盘符,比如记录到注册表某个神秘的地方,等到要装盘符的时候再装上。

CodeHz 发表于 2021-1-14 22:26:08

dos时代菜鸟 发表于 2021-1-14 22:11
你是说,
有盘符,就卸载,
没盘符,就加载?


楼主应该是写错了,应该是这样的情况

初始状态 没挂载 已挂载
参数:挂载 找一个没用的盘符挂上 返回这个盘符
参数:卸载 卸载自己挂载的盘符 啥也不动
使用场景应该是先执行挂载,然后等用户操作完,再执行卸载(

dos时代菜鸟 发表于 2021-1-14 22:48:05

CodeHz 发表于 2021-1-14 22:26
楼主应该是写错了,应该是这样的情况
使用场景应该是先执行挂载,然后等用户操作完,再执行卸载(

那,可以做成这样的:可好,
不带任何参数,就等待确认
有参数时,参数分 挂/卸 两种
挂,判断有无盘符,无,就挂之,有,就不动。
卸,判断有无盘符,有,就卸之,无,就不动。

liuzhaoyzz 发表于 2021-1-14 22:54:25

如有原来有盘符,就不用动原来的。如果没有就卸载批处理分配的,维持原状,保持现场。

dos时代菜鸟 发表于 2021-1-14 23:51:13

liuzhaoyzz 发表于 2021-1-14 22:54
如有原来有盘符,就不用动原来的。如果没有就卸载批处理分配的,维持原状,保持现场。

举例说明吧

liuzhaoyzz 发表于 2021-1-15 07:44:40

本帖最后由 liuzhaoyzz 于 2021-1-15 07:57 编辑

dos时代菜鸟 发表于 2021-1-14 22:11
你是说,
有盘符,就卸载,
没盘符,就加载?

这么晚了还没睡啊?辛苦了!
完整地描述下我的需求:
1.查找启动分区,如果原来有盘符比如G:盘,直接告知用户,不要再重复挂载一个Z:盘让用户迷惑。
2.提供个参数比如/D卸载启动分区盘符,不是强制卸载,如果启动分区原来有盘符比如G:盘,就不要卸载这个G:盘,即使执行了/D参数也不卸载G:盘,维持原状,强制卸载让用户自己手工搞定去;如果启动分区原来没有盘符,这个/D参数就卸载程序分配的盘符。
3.如果能够支持XP下判断启动分区更好,现在很多电脑不只有一个硬盘。
4.如果能够支持bootmgr/bootmgfw.efi→pe.wim这个场景能够判断启动分区最好,如果不行也没什么。
      

dos时代菜鸟 发表于 2021-1-15 11:35:30

本帖最后由 dos时代菜鸟 于 2021-1-15 12:30 编辑

liuzhaoyzz 发表于 2021-1-15 07:44
这么晚了还没睡啊?辛苦了!
完整地描述下我的需求:
1.查找启动分区,如果原来有盘符比如G:盘,直接 ...
这个 尝试判断 cmd 版本,来运行 bcdedit ,不知 xp 下是否可行。
内附 调用例子,

不带参数,运行 dpy.354.cmd 会根据情况 提示用户 是否挂、卸。



下图:运行例子,带参数,当目标分区被找到,并原始有盘符的情况下:



当目标分区 原始无盘符的情况下



当双击dpy.354.cmd ,目标分区没有盘符时,会提示用户挂载



应用例子:cmd 代码如下:
@echo off
setlocal ENABLEDELAYEDEXPANSION

set cmd_file="dpy.36.cmd"
set tempfile2="%temp%\old_bcd_ltr.temp"
set tempfile3="%temp%\new_bcd_ltr.temp"

echo 尝试挂载.....
call !cmd_file! /mount
if exist !tempfile2! (
    echo 盘符原始存在,不必挂载。
)
for /f %%c in ('type !tempfile3!') do (set "bcd_ltr=%%c")
if defined bcd_ltr (
    echo ---------------------------------------------------------
    echo **
    echo **
    echo ** 盘符是:!bcd_ltr!
    echo ** 此处运行想要运行的程序
    echo *.
    echo *.
    echo *.
    echo *.
    echo ---------------------------------------------------------
    echo 尝试卸载....
    if not exist !tempfile2! (
      call !cmd_file! /dismount
    ) else (
      echo 盘符原始存在,不必卸载。
    )
) else (
    echo.
    echo.
    echo 未探测到 BCD_Volume 。。。
)

echo.
echo.
pause


页: 1 2 3 4 5 6 7 8 9 [10] 11 12 13 14
查看完整版本: 请问下有没有办法用批处理或者命令行小程序确定系统引导分区?