Windows系统中能否获取UEFI变量列表?
枚举所有UEFI变量及命名空间的方法
Windows公开API里确实没有直接提供枚举所有UEFI变量的函数,但有两种可靠的实现方式:
1. 使用公开的WMI类(推荐,Windows 8+)
从Windows 8开始,微软提供了MSFT_UefiVariable WMI类(位于root\Microsoft\Windows\Boot命名空间),可以直接获取所有UEFI变量的完整信息,包括命名空间GUID、变量名、值、属性等。
PowerShell示例
用管理员权限运行以下命令即可列出所有UEFI变量:
Get-CimInstance -Namespace root/Microsoft/Windows/Boot -ClassName MSFT_UefiVariable
编程实现(C#示例)
如果要编写工具,可以通过WMI接口调用该类:
using System.Management; var scope = new ManagementScope(@"root\Microsoft\Windows\Boot"); var query = new ObjectQuery("SELECT * FROM MSFT_UefiVariable"); using (var searcher = new ManagementObjectSearcher(scope, query)) { foreach (var obj in searcher.Get()) { Console.WriteLine($"GUID: {obj["Namespace"]}"); Console.WriteLine($"变量名: {obj["Name"]}"); Console.WriteLine("---"); } }
2. 使用未文档化的Win32 API(兼容旧系统)
对于Windows 7及更早版本,或者需要更底层的实现,可以调用kernel32.dll中未公开的EnumSystemFirmwareEntries和EnumSystemFirmwareValues函数:
EnumSystemFirmwareEntries:枚举所有UEFI命名空间(GUID)EnumSystemFirmwareValues:针对指定GUID,枚举该命名空间下的所有变量名
C++示例
#include <windows.h> #include <iostream> #include <vector> #include <string> // 函数原型定义 typedef BOOL(WINAPI* EnumSystemFirmwareEntriesFn)(GUID*, DWORD*, DWORD*); typedef BOOL(WINAPI* EnumSystemFirmwareValuesFn)(const GUID*, PWSTR*, DWORD*, DWORD*); int main() { HMODULE hKernel = LoadLibrary(L"kernel32.dll"); if (!hKernel) return 1; auto pEnumEntries = (EnumSystemFirmwareEntriesFn)GetProcAddress(hKernel, "EnumSystemFirmwareEntries"); auto pEnumValues = (EnumSystemFirmwareValuesFn)GetProcAddress(hKernel, "EnumSystemFirmwareValues"); if (!pEnumEntries || !pEnumValues) { FreeLibrary(hKernel); return 1; } // 枚举所有命名空间GUID DWORD bufSize = 0, count = 0; pEnumEntries(nullptr, &bufSize, &count); std::vector<GUID> guids(count); if (!pEnumEntries(guids.data(), &bufSize, &count)) { FreeLibrary(hKernel); return 1; } // 遍历每个GUID,枚举变量 for (const auto& guid : guids) { WCHAR guidStr[40]; StringFromGUID2(guid, guidStr, ARRAYSIZE(guidStr)); std::wcout << L"命名空间GUID: " << guidStr << L"\n"; DWORD valBufSize = 0, valCount = 0; pEnumValues(&guid, nullptr, &valBufSize, &valCount); std::vector<WCHAR> valBuf(valBufSize / sizeof(WCHAR)); if (!pEnumValues(&guid, valBuf.data(), &valBufSize, &valCount)) continue; PWSTR pVal = valBuf.data(); for (DWORD i = 0; i < valCount; ++i) { std::wcout << L" 变量名: " << pVal << L"\n"; pVal += wcslen(pVal) + 1; } std::wcout << L"\n"; } FreeLibrary(hKernel); return 0; }
注意事项
- 所有访问UEFI变量的操作都需要管理员权限,否则会返回权限错误。
- 未文档化的API可能随Windows版本更新发生变化,优先使用WMI方案保证兼容性。
- 部分UEFI变量可能受固件保护,无法读取或修改。
内容的提问来源于stack exchange,提问作者Edward Falk
相关产品推荐
相关产品推荐

