找回密码
 加入
搜索
查看: 5065|回复: 14

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

 火.. [复制链接]
发表于 2016-1-14 15:44:35 | 显示全部楼层 |阅读模式
本帖最后由 chishingchan 于 2016-2-6 02:30 编辑

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

答案在12楼
发表于 2016-1-14 15:50:37 | 显示全部楼层
想到的思路是用Hwinfo之类的东西导出文本报告,然后从文本报告中识别关键字判断了。。。。
 楼主| 发表于 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/web ... ed~UEFI~or~BIOS.txt
请原谅我的渣DLLCALL
参考了 https://www.autoitscript.com/for ... -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[0] Then
        Return SetError(1, 0, 0)
    EndIf

    Return $aRet[3] ; 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}
 楼主| 发表于 2016-1-15 13:06:25 | 显示全部楼层
回复 4# 虫子樱桃


    谢谢分享!我的XP系统返回 UEFI Boot Mode 那肯定不对的!
 楼主| 发表于 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;
}
 楼主| 发表于 2016-1-18 19:31:17 | 显示全部楼层
现在想到了一种办法,使用内置命令 bcdedit 的输出信息进行识别,关键行:
path                    \EFI\MICROSOFT\BOOT\BOOTMGFW.EFI

path                    \Windows\system32\winload.efi
发表于 2016-1-19 00:25:37 | 显示全部楼层
不错的想法....
发表于 2016-1-20 11:21:42 | 显示全部楼层
进BIOS/UEFI看一下就知道了,假如是UEFI,有可能有"仅UEFI"和"UEFI+BIOS"两种方式,而后者又分"UEFI优先和BIOS优先"两种方式,在系统里不一定能绝对看得出来...
 楼主| 发表于 2016-1-24 15:41:14 | 显示全部楼层
回复 9# 邪恶海盗


    海盗大哥!编程不能靠肉眼来判断的。
发表于 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


已经测试通过!!!
发表于 2016-2-4 22:34:33 | 显示全部楼层
虫子樱桃厉害!
 楼主| 发表于 2016-2-6 02:29:43 | 显示全部楼层
回复 12# 虫子樱桃


    不能只用"谢谢"两个字来表达!
发表于 2016-9-8 14:38:45 | 显示全部楼层
回复 12# 虫子樱桃


    就楼主的要求来看,是解决问题了,因为在Legacy BIOS机器上返回错误值确实为1,在UEFI机器上返回错误值998,内存地址访问无效。不过就函数本身来说,虫子你的这个api似乎没有写对,函数的原型前面三个参数明明是指针,你这样写法地址为空,函数无法读取数据嘛。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-12-24 03:43 , Processed in 0.077889 second(s), 23 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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