chishingchan 发表于 2016-1-14 15:44:35

[已解决] 请问如何获取主板是否支持 Legacy 或 UEFI 启动?

本帖最后由 chishingchan 于 2016-2-6 02:30 编辑

Legacy BIOS 传统BIOS,之前应该所有的电脑都支持。UEFI 现在新的电脑一般都带有 UEFI 启动或同时支持 Legacy BIOS 启动;还有的新电脑只包含 UEFI 启动(像平板、盒子的系统)而不包含Legacy BIOS启动。请问 autoit3 能没有办法获取这方面的信息?或者有没有第三方命令行软件可用?谢谢!

答案在12楼

sanfer8889 发表于 2016-1-14 15:50:37

想到的思路是用Hwinfo之类的东西导出文本报告,然后从文本报告中识别关键字判断了。。。。

chishingchan 发表于 2016-1-14 17:01:18

谷歌外国网站,发现有3种方法可以获取:
1、运行msinfo32查看BIOS Mode值;
2、打开C:\Windows\Panther\Setupact.log日志文件,查找:Detected boot environment:后面的值;
3、运行两行命令行:
wpeutil UpdateBootInfo
reg query HKLM\System\CurrentControlSet\Control /v PEFirmwareType
查看返回值:
        0x1 代表电脑以 Legacy BIOS 模式启动
        0x2 代表电脑以 UEFI 模式启动

虫子樱桃 发表于 2016-1-14 23:40:14

本帖最后由 虫子樱桃 于 2016-1-14 23:43 编辑

找到这个,但是不会转换,转换的不晓得对不对
http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/nftechsupt.web+WinBatch/DllCall~Information+Booted~UEFI~or~BIOS.txt
请原谅我的渣DLLCALL
参考了 https://www.autoitscript.com/forum/topic/167827-uefi-or-bios-boot-dllcall-help/

#include <WinAPI.au3>
Global Const $ERROR_INVALID_FUNCTION=0x1
Func _WinAPI_GetFirmwareEnvironmentVariable($sName, $sGUID)

    If Not StringLen($sName) Then
      ; variable cannot be null
      Return SetError(1, 0, 0)
    EndIf

    Local $aRet = DllCall("Kernel32.dll", "dword", _
      "GetFirmwareEnvironmentVariableW", "wstr", $sName, _
      "wstr", $sGUID, "wstr", "", "dword", 4096)

    If @error Or Not $aRet Then
      Return SetError(1, 0, 0)
    EndIf

    Return $aRet ; pBuffer
EndFunc
_WinAPI_GetFirmwareEnvironmentVariable(Null, '{00000000-0000-0000-0000-000000000000}')
If _WinAPI_GetLastError() = $ERROR_INVALID_FUNCTION Then
    MsgBox(0,'','Legacy BIOS')
Else
    MsgBox(0,'','UEFI Boot Mode')
EndIf
;~ {00000000-0000-0000-0000-000000000000}

chishingchan 发表于 2016-1-15 13:06:25

回复 4# 虫子樱桃


    谢谢分享!我的XP系统返回 UEFI Boot Mode 那肯定不对的!

chishingchan 发表于 2016-1-15 13:45:48

本帖最后由 chishingchan 于 2016-1-18 10:33 编辑

DetectEFI.cpp#include <windows.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
        GetFirmwareEnvironmentVariableA("","{00000000-0000-0000-0000-000000000000}",NULL,0);
        if (GetLastError() == ERROR_INVALID_FUNCTION) { // This.. is.. LEGACY BIOOOOOOOOS....
                printf("Legacy");
                return 1;
        } else {
                printf("UEFI");
                return 0;
        }
        return 0;
}

chishingchan 发表于 2016-1-18 19:31:17

现在想到了一种办法,使用内置命令 bcdedit 的输出信息进行识别,关键行:
path                  \EFI\MICROSOFT\BOOT\BOOTMGFW.EFI

path                  \Windows\system32\winload.efi

ddrs 发表于 2016-1-19 00:25:37

不错的想法....

邪恶海盗 发表于 2016-1-20 11:21:42

进BIOS/UEFI看一下就知道了,假如是UEFI,有可能有"仅UEFI"和"UEFI+BIOS"两种方式,而后者又分"UEFI优先和BIOS优先"两种方式,在系统里不一定能绝对看得出来...

chishingchan 发表于 2016-1-24 15:41:14

回复 9# 邪恶海盗


    海盗大哥!编程不能靠肉眼来判断的。

xz00311 发表于 2016-1-28 15:51:08

希望解决后能出源码,让后来人学习一下

虫子樱桃 发表于 2016-1-30 16:56:33

本帖最后由 虫子樱桃 于 2016-1-30 17:19 编辑

#include <WinAPI.au3>
Global Const $ERROR_INVALID_FUNCTION=0x1
DllCall("Kernel32.dll", "dword", "GetFirmwareEnvironmentVariableW", "wstr", "", "wstr", '{00000000-0000-0000-0000-000000000000}', "wstr", Null, "dword", 0)
If _WinAPI_GetLastError() = $ERROR_INVALID_FUNCTION Then
    MsgBox(0,'','Legacy BIOS')
Else
    MsgBox(0,'','UEFI Boot Mode')
EndIf

已经测试通过!!!

love008 发表于 2016-2-4 22:34:33

虫子樱桃厉害!

chishingchan 发表于 2016-2-6 02:29:43

回复 12# 虫子樱桃


    不能只用"谢谢"两个字来表达!

haijie1223 发表于 2016-9-8 14:38:45

回复 12# 虫子樱桃


    就楼主的要求来看,是解决问题了,因为在Legacy BIOS机器上返回错误值确实为1,在UEFI机器上返回错误值998,内存地址访问无效。不过就函数本身来说,虫子你的这个api似乎没有写对,函数的原型前面三个参数明明是指针,你这样写法地址为空,函数无法读取数据嘛。
页: [1]
查看完整版本: [已解决] 请问如何获取主板是否支持 Legacy 或 UEFI 启动?