如何从Windows注册表读取REG_DWORD类型值并转换为wstring
解决方案
问题根源
现有代码无差别将REG_SZ和REG_DWORD类型的注册表值都按字符串格式读取处理。REG_DWORD是4字节长度的数值类型,值为1时对应的二进制内容为0x01 0x00 0x00 0x00,拷贝到wstring后会被后续查找空字符截断的逻辑直接处理为空字符串。
修复代码
需要按注册表值的类型分支处理,REG_DWORD先读取为数值再转换为wstring格式,修改后的完整代码如下:
wstring UpgradeAutocompleteBeCopyFilesUt::ReadRegValue(HKEY root, wstring key, wstring name) { HKEY hKey; if (RegOpenKeyEx(root, key.c_str(), 0, KEY_READ, &hKey) != ERROR_SUCCESS) throw "Could not open registry key"; DWORD type; DWORD cbData; if (RegQueryValueEx(hKey, name.c_str(), NULL, &type, NULL, &cbData) != ERROR_SUCCESS) { RegCloseKey(hKey); throw "Could not read registry value"; } if (type != REG_SZ && type != REG_DWORD) { RegCloseKey(hKey); throw "Incorrect registry value type"; } wstring value; if (type == REG_SZ) { // 原有REG_SZ处理逻辑 value.resize(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"; } size_t firstNull = value.find_first_of(L'\0'); if (firstNull != wstring::npos) value.resize(firstNull); } else { // REG_DWORD分支处理 DWORD dwordVal = 0; if (cbData != sizeof(DWORD)) { RegCloseKey(hKey); throw "Invalid DWORD value length"; } if (RegQueryValueEx(hKey, name.c_str(), NULL, NULL, reinterpret_cast<LPBYTE>(&dwordVal), &cbData) != ERROR_SUCCESS) { RegCloseKey(hKey); throw "Could not read registry value"; } value = to_wstring(dwordVal); } RegCloseKey(hKey); return value; }
改动说明
- 保留原有
REG_SZ类型的处理逻辑,原有功能不受影响 - 新增
REG_DWORD分支处理:先读取值到DWORD类型变量,再调用std::to_wstring转换为字符串格式 - 修复了原代码中误用
string::npos处理wstring的隐性问题
内容的提问来源于stack exchange,提问作者Apuna12
相关产品推荐
相关产品推荐

