windows注册表操作必须使用windows api,不可用标准库;需正确处理根键、权限、缓冲区大小、字符串编码及句柄关闭。
Windows 注册表在 C++ 中不能直接用标准库操作,必须调用 Windows API 的 RegOpenKeyEx、RegQueryValueEx、RegSetValueEx 等函数;不处理错误码、不关闭句柄、忽略权限问题,90% 的注册表操作会失败或静默失效。
用 RegOpenKeyEx 打开注册表路径前必须确认根键和访问权限
注册表路径如 HKEY_LOCAL_MACHINESOFTWAREMyApp 不能直接传给 API —— 根键(如 HKEY_LOCAL_MACHINE)是预定义句柄,路径部分必须拆出来单独传参。同时,REGSAM 权限标志不能硬写 KEY_ALL_ACCESS:普通用户进程默认无权写入 HKEY_LOCAL_MACHINE,应按需选择 KEY_READ 或 KEY_WRITE,写入时优先尝试 HKEY_CURRENT_USER。
- 读取示例:
RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\MyApp", 0, KEY_READ, &hKey) - 写入示例(需管理员权限):
RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\MyApp", 0, KEY_WRITE, &hKey) - 若返回
ERROR_ACCESS_DENIED,别强行提权,改用HKEY_CURRENT_USER存储用户级配置
RegQueryValueEx 读取值时必须先获取缓冲区大小,否则容易崩溃
注册表值类型多样(REG_SZ、REG_DWORD、REG_QWORD 等),RegQueryValueEx 第一次调用常用来“试探”数据长度,此时传入 nullptr 和 0 给缓冲区参数,API 会通过 lpcbData 返回所需字节数。跳过这步直接分配固定大小缓冲区,对字符串易截断,对二进制数据则可能越界读。
- 正确流程:先调用一次获取
dwSize,再new BYTE[dwSize],再第二次调用真正读取 - 读
REG_DWORD可简化:DWORD dwVal; RegQueryValueEx(hKey, L"Timeout", nullptr, nullptr, (LPBYTE)&dwVal, sizeof(dwVal)) - 读
REG_SZ注意:返回的是 UTF-16 字符串,末尾有双 ,std::wstring构造时要用size / sizeof(wchar_t)计算字符数
RegSetValueEx 写入字符串或数字时类型与缓冲区必须严格匹配
写入值的 dwType 参数必须与实际数据类型一致,且 lpData 指向的数据布局要符合该类型规范。常见错误是把 std::string 直接传给 REG_SZ,或把 int 地址传给 REG_DWORD 却忘了指针解引用。