本帖最後由 阿達金田一 於 2021-8-17 08:29 編輯
之前在別的主題...也有遇到有這需求的問題
https://inonameteam.com/forum.php?mod=viewthread&tid=5883&fromuid=211
用 bat 判斷 uefi 其它還真的不太方便
如果可以 最好還是用可以判斷 UEFI/BIOS 的 Console 程式
把判斷結果丟給 BAT 用 會比較方便和精準
網上可以 google 到很多方法
其實基本上都是用了其它程式來判斷
例如
用 bcdedit 來判斷
但 bcdedit 嚴格來說 其實也不完全是 判斷當前環境
因為 bcdedit 是用 系統啟動分區 和 系統BCD ( 而不是 PE 啟動分區 和 BCD )
所以如果是用 bcdedit /enum {current} 來判斷 winload.exe 或 winload.efi
在 PE 下判斷可能就不正確 因為可能不會有 {current}
( 除非你 PE 是用 系統啟動分區BCD 來啟動的 )
而用 bcdedit /enum {fwbootmgr} 倒是可以 ( 因為這是判斷 FireWare )
但前提是 系統啟動分區 和 系統BCD 要存在而且是正常的
因為 bcdedit 是先檢查 系統啟動分區 和 系統BCD ...
所以如果這2個有問題... bcdedit 就直接 error 結束了...也不會去查看 {fwbootmgr}
其它像 PE 下判斷的方式
https://docs.microsoft.com/zh-tw/windows-hardware/manufacture/desktop/boot-to-uefi-mode-or-legacy-bios-mode
wpeutil UpdateBootInfo
for /f "tokens=2* delims= " %%A in ('reg query HKLM\System\CurrentControlSet\Control /v PEFirmwareType') DO SET Firmware=%%B
:: Note: delims is a TAB followed by a space.
if %Firmware%==0x1 echo The PC is booted in BIOS mode.
if %Firmware%==0x2 echo The PC is booted in UEFI mode.
其實一樣還是用了 wpeutil UpdateBootInfo 來產生 Firmware 資料...再用 reg 和 bat指令 判斷
要比較準確判當前的 UEFI/BOIS...最好還是用 WinAPI
GetFirmwareEnvironmentVariable
XP ~ win8.1 適用 ( win10 要用比較麻煩...有程式即時權限問題 )
GetFirmwareType
win8 後適用 ... 沒程式權限問題
例如
我自己寫的 FwType.au3 ( 編譯成 console exe )
Console 和 ExitCode 會回傳
1 Legacy
2 UEFI
其它 Unknown
#pragma compile(Console, true)
#include <WinAPI.au3>
Func FwType1()
DllCall("Kernel32.dll", "dword", "GetFirmwareEnvironmentVariableW", "wstr", "", "wstr", '{00000000-0000-0000-0000-000000000000}', "wstr", Null, "dword",0)
Switch _WinAPI_GetLastError()
Case 1
Return 1
Case 998
Return 2
Case Else
Return 0
EndSwitch
EndFunc
Func FwType2()
Local $aCall = DllCall("Kernel32.dll", "int", "GetFirmwareType", "int*", 0)
If Not @error And $aCall[0] Then Return $aCall[1]
Return SetError(1, 0, 0)
EndFunc
$ret=0
Switch @OSVersion
Case "WIN_7", "WIN_VISTA", "WIN_XP", "WIN_XPe", "WIN_2008R2", "WIN_2008", "WIN_2003"
$ret=FwType1()
Case Else
$ret=FwType2()
EndSwitch
ConsoleWrite($ret&@CRLF)
Exit $ret
bat 用 bcdedit 和 wpeutil.exe ( 前題是 bcdedit 和 wpeutil 都可以正常執行)
另外 wpeutil UpdateBootInfo 推測是用 WinAPI GetFirmwareType 來判斷 FirmwareType
所以在 7pe , wpeutil UpdateBootInfo 無效
@echo off
call :FwType
echo %Firmware%
if %Firmware% EQU 1 echo Legacy BIOS
if %Firmware% EQU 2 echo UEFI
exit/b
REM FwType SUB
:FwType
set Firmware=0
if /i "%windir%"=="X:\Windows" (call :FwPE) else (call :FwWin)
exit/b
:FwWin
>nul bcdedit /enum {bootmgr} || exit/b
>nul bcdedit /enum {fwbootmgr} && set Firmware=2 || set Firmware=1
exit/b
:FwPE
if exist "%windir%\system32\wpeutil.exe" wpeutil UpdateBootInfo
for /f "tokens=2*" %%a in ('reg query HKLM\System\CurrentControlSet\Control /v PEFirmwareType') do set /a Firmware=%%b
exit/b
REM FwType SUB END
|