必须检查regopenkeyex返回值,用if(result!=error_success)判断;32/64位需显式指定key_wow64_64key等标志;读字符串需两次调用regqueryvalueex;写入时cbdata须严格匹配类型字节数;句柄须手动配对regclosekey。

用 RegOpenKeyEx 打开注册表项前必须检查返回值
windows 注册表 API 不会抛异常,所有错误都靠返回值判断。直接忽略 RegOpenKeyEx 的返回值,很容易在后续 RegQueryValueEx 时崩掉或读到垃圾数据。
常见错误现象:ERROR_FILE_NOT_FOUND(路径不存在)、ERROR_ACCESS_DENIED(权限不足,尤其写 64 位系统上的 HKEY_LOCAL_MACHINE)、ERROR_SUCCESS 被当成布尔真但其实只是非零整数。
- 永远用
if (result != ERROR_SUCCESS)判断,别用if (!result) - 32/64 位程序在 WoW64 环境下默认重定向注册表视图(比如
HKEY_LOCAL_MACHINESoftware会被映射到Wow6432Node),需要显式传KEY_WOW64_64KEY或KEY_WOW64_32KEY控制 - 打开
HKEY_LOCAL_MACHINE写入时,程序必须以管理员权限运行,否则RegCreateKeyEx会返回ERROR_ACCESS_DENIED
RegQueryValueEx 读字符串要先调用两次
注册表里字符串(REG_SZ、REG_EXPAND_SZ)长度不固定,API 不提供“获取长度”独立函数,只能靠两次调用:第一次获取缓冲区大小,第二次读内容。
容易踩的坑是只调一次,传个固定大小的 char[256] 就完事——要么截断,要么缓冲区溢出(如果没检查 lpcbData 输出值)。
立即学习“C++免费学习笔记(深入)”;
- 第一次调用传
nullptr给lpData,用lpcbData拿到所需字节数(注意是字节,不是字符;Unicode 下wchar_t是 2 字节) - 第二次分配足够内存(记得 +1 个空终止符位置),再读
- 别忘了判断
dwType是否真的是REG_SZ,否则可能读到REG_DWORD却当字符串用
写注册表用 RegSetValueEx,但类型和长度必须严格匹配
RegSetValueEx 的 cbData 参数是字节数,不是字符数,也不是元素个数。传错就导致键值损坏或写入失败。
典型场景:写一个 REG_SZ 字符串 L"Hello",有人直接传 sizeof(L"Hello")——这其实是 12(6 个 wchar_t × 2),但正确值是 (wcslen(str) + 1) * sizeof(wchar_t),即 12;而写 REG_DWORD 时,cbData 必须是 sizeof(DWORD)(4),多 1 字节或少 1 字节都会让读取失败。
-
REG_SZ和REG_EXPAND_SZ的值必须以