在x86和x64架构中获取Windows序列号(MachineGuid)

5

我目前使用以下C ++代码从Windows注册表中获取MachineGuid并将该信息用于我的许可算法:

std::wstring key = L"SOFTWARE\\Microsoft\\Cryptography";
std::wstring name = L"MachineGuid";

HKEY hKey;

if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, key.c_str(), 0, KEY_READ, &hKey) != ERROR_SUCCESS)
    throw std::runtime_error("Could not open registry key");

DWORD type;
DWORD cbData;

if (RegQueryValueEx(hKey, name.c_str(), NULL, &type, NULL, &cbData) != ERROR_SUCCESS)
{
    RegCloseKey(hKey);
    throw std::runtime_error("Could not read registry value");
}

if (type != REG_SZ)
{
    RegCloseKey(hKey);
    throw "Incorrect registry value type";
}

std::wstring value(cbData/sizeof(wchar_t), L'\0');
if (RegQueryValueEx(hKey, name.c_str(), NULL, NULL, reinterpret_cast<LPBYTE>(&value[0]), &cbData) != ERROR_SUCCESS)
{
    RegCloseKey(hKey);
    throw "Could not read registry value";
}

RegCloseKey(hKey);

这在x86系统(32位)上效果很好。现在我已经将整个代码迁移到了x64(64位)Windows,但RegQueryValueEx调用返回错误。
在一些其他帖子中,这个链接非常清楚地解释了为什么在64位机器上不起作用,并提供了一个替代方案,使用来自System.Management.dllManagementObject类适用于32位和64位。问题是这个解决方案只适用于C#,而不适用于C++。我找不到C++中与ManagementObject类相当的方法。
那么,如何才能正确解决问题:在x86和x64机器上都能获取窗口序列号(MachineGuid)并使用C++。
感谢您的帮助。

1
WMI可以通过COM API在C++应用程序中使用。我建议查看使用C++创建WMI应用程序。您将需要执行一个WQL查询(类似于SQL)来查询其中一个Win32_Provider类。目前我无法告诉您哪个类包含“MachineGuid”的等效项。Win32_ComputerSystem可能是您的起点。 - Jonathon Ogden
如果您继续追求WMI解决方案,Win32_ComputerSystemProduct UUID 可能与Windows操作系统“系统信息”应用程序中找到的UUID相关联,这是我在快速浏览中找到的可能与MachineGuid相关的内容。 - Jonathon Ogden
1个回答

6
在您的RegOpenKeyEx参数中添加KEY_WOW64_64KEY位。像这样:
RegOpenKeyEx( HKEY_LOCAL_MACHINE, key.c_str(), 0, KEY_READ | KEY_WOW64_64KEY, &hKey )

文档中指出,它在32位操作系统上被忽略,因此您甚至不需要检测WOW64。

另外,我不推荐使用WMI,它太慢了。我目前使用的是i5-4460 CPU,16GB RAM,相对较快的SSD,但即使是简单的查询,WMI也需要1-2秒钟才能初始化和运行。


谢谢...我应该为32位和64位实现都添加KEY_WOW64_64KEY,还是只为64位选项添加并保留32位而不添加? - Mendes
只为32位工作,但为两者添加是无害的。 - Soonts

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接