Windows下最可靠方式是WMI查询Win32_BIOS类,Linux优先读/sys/class/dmi/id/bios_version或用dmidecode,macOS无法获取BIOS版本只能返回空或"N/A"。

Windows下用WMI查询BIOS版本最可靠
直接调用系统API几乎不可能拿到BIOS版本,Windows平台唯一稳定可行的方式是走WMI(Windows Management Instrumentation)。Win32_BIOS类提供了Version、Manufacturer、ReleaseDate等字段,比注册表或SMBIOS解析更兼容、权限要求更低。
常见错误是试图用GetSystemFirmwareTable——它只返回固件类型(如“ACPI”、“FIRM”),不包含版本字符串;还有人查注册表HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\BIOS,但该路径在Win10/11中常为空或不更新。
- 必须链接
comsuppw.lib并初始化COM:CoInitializeEx(nullptr, COINIT_MULTITHREADED) - WQL查询语句写成
"SELECT Version, Manufacturer FROM Win32_BIOS",别漏掉SELECT和空格 - 返回的
Version可能是类似"American Megatrends Inc. 5.12"的字符串,需按空格或厂商前缀截取,不能直接当纯版本号用 - 如果WMI服务被禁用(
wmiprvse.exe没运行),查询会超时或返回WBEM_E_ACCESS_DENIED,需提示用户检查服务状态
Linux下读取/sys/firmware/acpi/tables或dmidecode输出
Linux没有统一API,dmidecode是最常用手段,但它需要root权限;而/sys/firmware/acpi/tables/SLIC或/sys/class/dmi/id/bios_version路径虽免权限,但部分发行版(如某些ARM设备或容器环境)可能缺失。
注意dmidecode输出不稳定:不同主板厂商对Bios Version:字段格式不一致,有的带空格缩进,有的含括号,比如"1.15.0"、"F.15 "、"AMI 2.17",硬匹配容易出错。
- 用
std::system("dmidecode -s bios-version 2>/dev/null")捕获stdout比自己fork+pipe更简单,但要过滤首尾空白和换行 -
/sys/class/dmi/id/bios_version文件存在时优先读它,内容通常是干净字符串,但得先access("/sys/class/dmi/id/bios_version", R_OK)判断可读性 - 不要依赖
/proc/sys/kernel/osrelease——那是内核版本,不是BIOS - 在WSL里跑
dmidecode会失败,因为虚拟层不透传DMI数据,此时只能回退到lshw -class system或直接报“不可用”
C++跨平台封装要注意的三处陷阱
写个get_bios_version()函数跨Windows/Linux时,最容易翻车的是路径/命令差异、权限静默失败、以及字符串编码。Windows WMI返回UTF-16,Linux文件系统默认UTF-8,混用std::string和std::wstring会导致乱码或截断。
- Windows侧必须用
std::wstring接收WMI结果,再转std::string时用WideCharToMultiByte(CP_UTF8, ...),别用std::wstring_convert(C++17已弃用) - Linux侧用
std::ifstream读/sys/...路径时,打开前加imbue(std::locale::classic())避免locale干扰 - 所有外部命令(如
dmidecode)执行后必须检查return code == 0,否则返回空字符串而不是抛异常——BIOS信息本就是可选硬件元数据,缺失不应中断主流程 - 缓存结果:BIOS版本开机后不会变,首次调用后存静态
std::string,避免重复查WMI或读文件
macOS上基本无解,别白费力气
macOS不暴露BIOS(实际是UEFI固件),也没有对应WMI或DMI机制。system_profiler SPHardwareDataType只显示“Boot ROM Version”,且该值由Apple签名锁定,第三方工具无法修改或完整读取;ioreg -l | grep "version"返回的多是SMC或EFI驱动版本,不是主板BIOS。
如果你的应用真需要这个字段,在macOS上只能返回空字符串或硬编码"N/A",试图用IOKit遍历IOPlatformExpertDevice获取boot-rom-version property也大概率失败——Apple从10.15开始限制了这些接口的访问权限。
真正麻烦的不是技术实现,而是用户期望:有人以为“所有系统都能查BIOS”,结果在Mac上看到空值就认为程序坏了。提前在文档里写明平台限制,比事后解释强得多。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











