Board logo

标题: [AU3基础] [已解决]可否判断C盘是活动分区并执行程序?感谢austere 帮助 [打印本页]

作者: 令狐大虾    时间: 2017-1-5 19:00     标题: [已解决]可否判断C盘是活动分区并执行程序?感谢austere 帮助

本帖最后由 令狐大虾 于 2017-1-8 22:05 编辑

在UEFI PE启动模式下释放WIM到C盘后运行bcdboot c:\windows /l zh-cn 后。
1.对于存在ESP隐藏区的GPT磁盘会将启动文件夹EFI写入ESP活动区。
2.但是对于UEFI启动的MBR磁盘必须
运行bcdboot c:\windows /l zh-cn /s c: 才能将启动文件夹EFI写入活动区C盘。
同样在GPT模式磁盘运行bcdboot c:\windows /l zh-cn /s c: 也会将启动文件夹EFI写入活动区C盘,只是安装时候出错不能启动。
3.两行命令在UEFI PE启动下同时执行适用与MBR和GPT模式磁盘。但对于GPT模式磁盘就显得多余。

论坛里面搜索,只是判断当前系统是否是UEFI启动而已。经过思考,GPR模式C盘不是活动区而MBR模式却是。所以判断C盘是否活动区而写入相应命令最准确。特别是对于多硬盘并且是混合模式硬盘下。
作者: austere    时间: 2017-1-5 20:12

GPT分区需要一个单独的16或者32的fat分区来保存UEFI的启动信息,请问这个分区的盘符你怎么判断?至于往分区内写uefi信息就简单了 bcdboot命令就可以搞定
另:uefi除了GPT分区适合,MBR分区用uefi我个人感觉就是个鸡肋,一点用都没有。。。
作者: 令狐大虾    时间: 2017-1-5 21:17

回复 2# austere

请看标题,我请教的是判断C盘是否是活动区。
还有,我并不觉得MBR是鸡肋。它可以用混合模式启动(MBR模式启动或是UEFI模式启动)。在帮客户安装系统的时候根本就不需要转换磁盘模式也可以UEFI启动。
作者: austere    时间: 2017-1-5 22:58

回复 3# 令狐大虾


    你的意思是MBR模式下,ghost恢复系统后用bcdboot修复uefi引导来实现不转换磁盘模式来uefi引导?
这种法我没实践过。。。
作者: 令狐大虾    时间: 2017-1-6 12:53

本帖最后由 令狐大虾 于 2017-1-6 17:41 编辑

回复 4# austere

不是GHOST恢复,是PE下释放WIM文件到C盘后再写入引导文件。当然你GHOST释放也可以。
此法不需要转换原来的MBR磁盘模式就可以UEFI引导启动,当然,玩这个方法的人不多。毕竟大多数人都是按照微软的方法折腾。
因为我是用自写的安装器安装,在UEFI PE下启动,对于MBR模式的磁盘磁盘用bcdboot c:\windows /l zh-cn /s c: 写入启动引导文件到活动区C盘(此命令在GPT下也会强制写入C盘),而对于GPT模式的磁盘用bcdboot c:\windows /l zh-cn 写入启动文件到活动区ESP。
所以我想判断C盘是不是活动区而执行命令。
作者: austere    时间: 2017-1-6 17:05

回复 5# 令狐大虾


    你那个判断C盘是不是活动分区那个我不会整,但是能给你一个方法判断硬盘是MBR模式还是GPT模式,目的能实现你的那个要求,MBR这个就不管了,默认你已经写了引导,如果是GPT模式的话,再把引导文件重新复制到引导分区
判断方法:用diskpart命令
开始--运行--输入 diskpart    然后输入 list disk   根据返回的信息来判断是否是GPT模式,如果是GPT模式则GPT显示下面会有*号   如果没有*号则为MBR模式
程序实现方法,C盘下新建一个文本文档 输入list disk 保存为 123.txt
用命令 diskpart c:\123.txt > c:\234.txt
然后获取234.txt里面的数组 进行判断
作者: austere    时间: 2017-1-6 17:12

针对多硬盘 list disk也会显示出其他硬盘,如果要进行判断的话,以磁盘 0为准,如果系统C盘是启动盘,怎么磁盘肯定为 磁盘0  根据这个来进行判断就好了
作者: 令狐大虾    时间: 2017-1-6 17:47

本帖最后由 令狐大虾 于 2017-1-6 17:53 编辑

回复 6# austere

你这个方法只是适合单硬盘。对于混合磁盘就是多硬盘不同模式就好比盲选一样。
作者: 令狐大虾    时间: 2017-1-6 17:48

本帖最后由 令狐大虾 于 2017-1-6 17:51 编辑
针对多硬盘 list disk也会显示出其他硬盘,如果要进行判断的话,以磁盘 0为准,如果系统C盘是启动盘,怎么磁 ...
austere 发表于 2017-1-6 17:12


磁盘0或1以下类推受SATA插口左右。而且是在PE下执行判断啊,先决系统是PE决定是磁盘0还是1
作者: austere    时间: 2017-1-6 20:25

PE下你系统确定是安装到C? 前面已经说了C肯定是 disk 0    具体你PE下测试一下,我用的Pe都是这样
作者: austere    时间: 2017-1-6 20:44

另外还可以用一个命令  diskpart然后输入list vol
这个会获取所有硬盘的分区信息。 然后根据回显内容看C盘 最后一栏信息中的信息。如果显示为系统则为mbr 其他的则为uefi
作者: 令狐大虾    时间: 2017-1-6 21:01

回复 10# austere

嗯,当然是安装到C盘,AU3例子麻烦写个给我。判断C盘所在的磁盘为MBR就执行程序即可
作者: austere    时间: 2017-1-6 22:10

回复 12# 令狐大虾
  1. #include <MsgBoxConstants.au3>
  2. #include <Array.au3>
  3. #include <File.au3>
  4. #include <Process.au3>

  5. If FileExists(@TempDir & "\disk\") = 0 Then _FileCreate(@TempDir & "\disk\")
  6. $file = _FileCreate(@TempDir & "\disk\list.txt")
  7.         $file1 = FileOpen($file, 1)
  8.         FileWrite(@TempDir & "\disk\list.txt", "list vol")

  9.         _RunDos("cmd.exe /c diskpart.exe /s " & @TempDir & "\disk\list.txt >"& @TempDir & "\disk\123.txt")
  10.         Local $aArray = FileReadToArray(@TempDir & "\disk\123.txt")
  11.         Local $asd = _ArrayFindAll($aArray, "  C  ", Default, Default, 1, 1, 2)
  12.                 $ss = StringStripWS($aArray[$asd[0]], 8)
  13.         Local $sss = StringRight($ss, 2)
  14.         If $sss == "启动" Then
  15.                 MsgBox(0,"","当前为UEFI启动")
  16.         Else
  17.                 msgbox(0,"","当前为MBR启动")
  18.         EndIf
  19.        
复制代码

作者: chishingchan    时间: 2017-1-6 22:23

看看这个合适:
  1. $objWMIService = ObjGet("winmgmts:\\.\root\cimv2")
  2. $colItems = $objWMIService.ExecQuery("Select * from Win32_DiskPartition")
  3. Dim $objItem
  4. For $objItem In $colItems
  5.         MsgBox(0, "主分区和扩展分区","磁盘索引: " & $objItem.DiskIndex & @CRLF & "分区索引: " & $objItem.Index & @CRLF & "主分区: " & $objItem.PrimaryPartition & @CRLF & "引导分区: " & $objItem.BootPartition & @CRLF & "可启动: " & $objItem.Bootable & @CRLF & "大小: " & $objItem.Size)
  6. Next
复制代码

作者: chishingchan    时间: 2017-1-6 22:30

回复 13# austere


    给你参考虫子樱桃的代码:
  1. #include <WinAPI.au3>
  2. Global Const $ERROR_INVALID_FUNCTION=0x1
  3. DllCall("Kernel32.dll", "dword", "GetFirmwareEnvironmentVariableW", "wstr", "", "wstr", '{00000000-0000-0000-0000-000000000000}', "wstr", Null, "dword", 0)
  4. If _WinAPI_GetLastError() = $ERROR_INVALID_FUNCTION Then
  5.     MsgBox(0,'','Legacy BIOS')
  6. Else
  7.     MsgBox(0,'','UEFI Boot Mode')
  8. EndIf
复制代码

作者: austere    时间: 2017-1-6 22:55

回复 15# chishingchan


    虫子的这个代码我看过,非常不错~ 不过和你这个不太一样,厉害~
作者: 令狐大虾    时间: 2017-1-7 01:30

回复  令狐大虾
austere 发表于 2017-1-6 22:10


此代码不行。
单独GPT磁盘启动,MBR或UEFI 8PE下运行此程序都显示为“当前为MBR启动”
作者: 令狐大虾    时间: 2017-1-7 01:31

看看这个合适:
chishingchan 发表于 2017-1-6 22:23


你这个等于是看磁盘索引之类。根本不是我需要的效果哈
作者: 令狐大虾    时间: 2017-1-7 01:35

回复  austere


    给你参考虫子樱桃的代码:
chishingchan 发表于 2017-1-6 22:30


这个早看过了
获取当前系统的启动模式而已。也达不到要求。因为我是MBR模式磁盘的UEFI启动!
作者: austere    时间: 2017-1-7 09:13

回复 18# 令狐大虾


    改下判断你再试下~
  1. #include <MsgBoxConstants.au3>
  2. #include <Array.au3>
  3. #include <File.au3>
  4. #include <Process.au3>

  5. If FileExists(@TempDir & "\disk\") = 0 Then _FileCreate(@TempDir & "\disk\")
  6. $file = _FileCreate(@TempDir & "\disk\list.txt")
  7.         $file1 = FileOpen($file, 1)
  8.         FileWrite(@TempDir & "\disk\list.txt", "list vol")

  9.         _RunDos("cmd.exe /c diskpart.exe /s " & @TempDir & "\disk\list.txt >"& @TempDir & "\disk\123.txt")
  10.         Local $aArray = FileReadToArray(@TempDir & "\disk\123.txt")
  11.         Local $asd = _ArrayFindAll($aArray, "  C  ", Default, Default, 1, 1, 2)
  12.                 $ss = StringStripWS($aArray[$asd[0]], 8)
  13.         Local $sss = StringRight($ss, 2)
  14.         If $sss == "系统" OR $sss == "system" Then
  15.                 MsgBox(0,"","当前为MBR启动")
  16.         Else
  17.                 msgbox(0,"","当前为UEFI启动")
  18.         EndIf
  19.         
复制代码
这个只是调换了一下判断而已,你再试下
作者: 令狐大虾    时间: 2017-1-7 11:25

回复 20# austere

多硬盘,UEFI 启动的MBR硬盘+GPT硬盘混合。误判为“当前为UEFI启动”。意思就是误判为GPT启动。

其实这两行字可以改为:“当前为MBR硬盘启动“,”当前为GPT硬盘启动”。因为GPT模式只能是UEFI启动
作者: austere    时间: 2017-1-7 12:50

回复 21# 令狐大虾


    这个只是判断一下C盘的启动模式,你就是挂载再多的硬盘,也只是判断C盘的~ 也就是说我系统安装到C盘或者恢复到C盘后,如果判断为MBR启动,那么你就执行你原有的那个boot命令到C就好了,如果判断为GPT模式,boot命令到另外划分的启动分区就好了。你要实现的不是这个目的?
作者: 令狐大虾    时间: 2017-1-7 16:00

本帖最后由 令狐大虾 于 2017-1-7 16:07 编辑
回复  令狐大虾


    这个只是判断一下C盘的启动模式,你就是挂载再多的硬盘,也只是判断C盘的~ 也就是 ...
austere 发表于 2017-1-7 12:50


理是这个理,但是却不一样的。
这么说吧:
1.前提必须是UEFI PE启动
2.UEFI PE下检测系统所在的C盘为MBR模式的磁盘。

而这个代码在UEFI PE下检测只是给我一个UEFI启动?那么我根本就不知道这个启动的磁盘是不是MBR模式磁盘。所以此代码仅仅是适合单个磁盘作为检测,并且它仅仅是MBR PE下执行也会给我返回是UEFI启动。。。。。。。。

大致明白了这个代码的原理就是检测磁盘主分区,超过一个主分区就判断为UEFI启动
作者: austere    时间: 2017-1-7 17:24

回复 23# 令狐大虾


    实际测试了一把,果真如你所说~  我是在win10下测试的,换了win8的PE进行测试,可能是因为diskpart版本问题,信息获取不到,所以会显示判断错误,晚上我再改下代码给你,你再试下~
作者: austere    时间: 2017-1-7 18:13

重新修改了一下,我进PE下测试了可以,你再试下~
  1. #include <MsgBoxConstants.au3>
  2. #include <Array.au3>
  3. #include <File.au3>
  4. #include <Process.au3>

  5. If FileExists(@TempDir & "\disk\") = 0 Then _FileCreate(@TempDir & "\disk\")
  6. $file = _FileCreate(@TempDir & "\disk\list.txt")
  7.         $file1 = FileOpen($file, 1)
  8.         FileWrite(@TempDir & "\disk\list.txt", "list disk")
  9.                

  10.         _RunDos("cmd.exe /c diskpart.exe /s " & @TempDir & "\disk\list.txt >"& @TempDir & "\disk\123.txt")
  11.         Local $aArray = FileReadToArray(@TempDir & "\disk\123.txt")
  12.         Local $asd = _ArrayFindAll($aArray, "磁盘 0", Default, Default, 1, 1, 2)
  13.                 $ss = StringStripWS($aArray[$asd[0]], 8)
  14.                 Local $sss = StringRight($ss, 1)
  15.         If $sss == "*"  Then
  16.                 msgbox(0,"","当前为UEFI启动")
  17.         Else
  18.                 MsgBox(0,"","当前为MBR启动")
  19.         EndIf
复制代码

作者: 令狐大虾    时间: 2017-1-7 23:15

回复 25# austere

搞掂了,这代码正确识别达到我需要的效果,我修改了一下文字还有添加两行命令进去。不过怎样在帖子里面如你这样好像一个图一样发出来并且下面又复制代码几个字?
作者: austere    时间: 2017-1-8 00:13

回复 26# 令狐大虾

[attach]31571[/attach]

如图,点击插入代码,然后把代码复制到里面就可以了~  或者直接使用高级里面的代码插入
作者: 令狐大虾    时间: 2017-1-8 14:59

回复 27# austere
  1. #include <MsgBoxConstants.au3>
  2. #include <Array.au3>
  3. #include <File.au3>
  4. #include <Process.au3>

  5. If FileExists(@TempDir & '\disk\') = 0 Then _FileCreate(@TempDir & '\disk\')
  6. $file = _FileCreate(@TempDir & '\disk\list.txt')
  7.         $file1 = FileOpen($file, 1)
  8.         FileWrite(@TempDir & '\disk\list.txt', 'list disk')
  9.                

  10.         _RunDos('cmd.exe /c diskpart.exe /s ' & @TempDir & '\disk\list.txt >'& @TempDir & '\disk\123.txt')
  11.         Local $aArray = FileReadToArray(@TempDir & "\disk\123.txt")
  12.         Local $asd = _ArrayFindAll($aArray, '磁盘 0', Default, Default, 1, 1, 2)
  13.                 $ss = StringStripWS($aArray[$asd[0]], 8)
  14.                 Local $sss = StringRight($ss, 1)
  15.         If $sss == '*'  Then
  16.                 msgbox(0,'','当前为GPT硬盘启动',1)
  17.                 _RunDos('cmd.exe /c bcdboot c:\windows /l zh-cn') ;确定C盘是GPT磁盘并将EFI启动文件夹写入活动区ESP盘      
  18.                 Else
  19.                 MsgBox(0,'','当前为MBR硬盘启动',1)
  20.                 _RunDos('cmd.exe /c bcdboot c:\windows /l zh-cn /s c:') ;确定C盘是MBR磁盘并将EFI启动文件夹写入活动区C盘,若MBR PE启动则将Boot启动文件夹写入活动区C盘
  21.                                  If FileExists(@HomeDrive & '\EFI') Then
  22.                                  FileSetAttrib('C:\EFI','+RSH')
  23.                  EndIf
  24.                 EndIf
复制代码

作者: austere    时间: 2017-1-8 22:44

回复 28# 令狐大虾


    你那个gpt模式用那个命令管用? 我看你没写esp分区盘符啊
作者: 令狐大虾    时间: 2017-1-8 23:14

本帖最后由 令狐大虾 于 2017-1-8 23:16 编辑
回复  令狐大虾


    你那个gpt模式用那个命令管用? 我看你没写esp分区盘符啊
austere 发表于 2017-1-8 22:44

管用啊,实体机测试通过。你没看我改了文字啊。我需要的是判断是啥模式的磁盘就直接把引导文件写入C盘,不需要写ESP盘符的
不过在03PE下运行出现diskpart错误,03PE里面也有diskpart.exe的,就是替换8PE的进去也不行
作者: 令狐大虾    时间: 2017-1-9 09:28

本帖最后由 令狐大虾 于 2017-1-9 09:35 编辑
管用啊,实体机测试通过。你没看我改了文字啊。我需要的是判断是啥模式的磁盘就直接把引导文件写入C盘,不 ...
令狐大虾 发表于 2017-1-8 23:14


其实系统安装无论是何种方式启动(MBR启动或UEFI启动模式),默认的启动文件写入方式都是
bcdboot c:\windows /l zh-cn(将启动文件写入硬盘主分区活动区)。

只是我有特殊要求才折腾而已。下面是DIY
一、bcdboot c:\windows /l zh-cn和bcdboot c:\windows /l zh-cn /s c:的区别(注意/s后面必须指定分区)
1. MBR模式的磁盘(无隐藏分区)
MBR 8PE启动执行bcdboot c:\windows /l zh-cn则会将启动文件夹BOOT(属性为隐藏)写入活动区C盘。
MBR 8PE启动执行bcdboot c:\windows /l zh-cn /s c: 也会将启动文件夹BOOT(属性为隐藏)写入活动区C盘。
UEFI 8PE下执行bcdboot c:\windows /l zh-cn无效!
UEFI 8PE下执行bcdboot c:\windows /l zh-cn /s c:则会将启动文件夹EFI(属性为只读)写入活动区C盘。
2.GPT模式磁盘(带隐藏分区ESP及MSR)
MBR 8PE启动执行bcdboot c:\windows /l zh-cn则不会写入任何启动文件,需要挂载ESP假设为x并执行 bcdboot c:\windows /l zh-cn /f uefi /s x:
MBR 8PE启动执行bcdboot c:\windows /l zh-cn /s c:则将启动文件夹Boot写入非活动区C盘。(即GPT硬盘不支持系统MBR启动模式启动,安装中会出现"windows安装程序无法将 windows 配置为在此计算机的硬件上运行。")
UEFI 8PE 启动执行bcdboot c:\windows /l zh-cn则将启动文件夹EFI写入隐藏的活动区ESP。
UEFI 8PE 启动执行bcdboot c:\windows /l zh-cn /s c: 则将启动文件夹EFI(属性为只读)写入非活动区C,。

由以上两个例子看出,只有在MBR PE下启动bcdboot c:\windows /l zh-cn= bcdboot c:\windows /l zh-cn /s c:

二、UEFI或MBR交替启动(硬盘必须为MBR模式!)
UEFI 8PE和MBR 8PE分别启动,任意一PE下将WIM释放到C盘之后各运行一次bcdboot c:\windows /l zh-cn /s c:
MBR PE下C盘根目录生成了boot文件夹 (MBR引导,属性为隐藏),UEFI PE 下C盘根目录生成了EFI文件夹(UEFI引导,属性为只读)
然后在主板设置里面自选启动方式

我为啥这样做安装器,就是我可以无视硬盘模式,意思不管它是MBR模式磁盘或是GPT模式磁盘都可以做到UEFI启动。
作者: austere    时间: 2017-1-9 10:01

回复 30# 令狐大虾


   没你那样用过,我用的时候GPT要把引导文件写esp分区里才可以引导的。
03PE的diskpart版本太低的原因,我一开始测试是在win10下测试的,你不是说有问题,所以我就用win8试了一下,确实有问题,然后才又改的,现在这个win7以上的pe用都是可以通过的,03版本不行
作者: 令狐大虾    时间: 2017-1-9 16:47

回复  令狐大虾


   没你那样用过,我用的时候GPT要把引导文件写esp分区里才可以引导的。
03PE的disk ...
austere 发表于 2017-1-9 10:01

嗯,反正03PE不支持UEFI启动,不需要加这个代码判断。
我的理解:搞系统制作在做系统安装的时候尽量减少客户的工作量(当然包括自己)。不需要按部就班按照大多数人或者微软提出的安装模式进行,而只是需要傻瓜式的轻轻一键操作即可。
作者: austere    时间: 2017-1-9 18:28

回复 33# 令狐大虾


    嗯,写代码的目的就是为了简化工作量,&#128513;




欢迎光临 AUTOIT CN (http://autoitx.com/) Powered by Discuz! 7.2