调用RegSetValueEx设置REG_SZ值仅保存前4字符的问题求助
C++ Windows注册表REG_SZ写入截断问题修复方案
问题根因
你代码的核心错误出在RegSetValueEx最后一个长度参数的计算:SetValSZ函数中data参数的类型是LPCTSTR,本质是指针类型,在32位编译环境下指针固定占4字节,因此sizeof(data)的返回值永远是4,这就是仅能存入前4个字符(对应2个宽字符,每个wchar_t占2字节)的直接原因。
另外REG_SZ类型要求传入的长度为字符串总字节数,必须包含末尾的\0空终止符。
修复代码
你只需要修改SetValSZ函数的长度计算逻辑即可,修正后的完整代码如下:
#include <windows.h> #include <stdio.h> #include <wchar.h> HKEY OpenKey(HKEY hRootKey, wchar_t* strKey) { HKEY hKey; // 如果需要访问64位注册表,权限改为KEY_ALL_ACCESS | KEY_WOW64_64KEY LONG nError = RegOpenKeyEx(hRootKey, strKey, 0, KEY_ALL_ACCESS, &hKey); if (nError == ERROR_FILE_NOT_FOUND) { printf("Debug: Creating registry key\n"); // 同上,需要访问64位注册表则追加KEY_WOW64_64KEY nError = RegCreateKeyEx(hRootKey, strKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL); } if (nError) { printf("Error: Could not find or create key, error code: %ld\n", nError); } return hKey; } void SetValSZ(HKEY hKey, LPCTSTR lpValue, LPCTSTR data) { // 计算带空终止符的总字节数 DWORD dataByteLen = (wcslen(data) + 1) * sizeof(wchar_t); LONG nError = RegSetValueEx(hKey, lpValue, 0, REG_SZ, (const BYTE*) data, dataByteLen); if (nError) printf("Error: Could not set registry value, error code: %ld\n", nError); } int main() { // 操作HKLM需要管理员权限,否则会打开失败 HKEY hKey = OpenKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Policies\\Microsoft\\FVE"); if (hKey == NULL) { return 1; } const wchar_t data[] = L"AAAABBBBCCCC"; SetValSZ(hKey, L"RecoveryKeyMessage", data); RegCloseKey(hKey); return 0; }
注意事项
- 操作
HKEY_LOCAL_MACHINE下的注册表项需要程序以管理员权限运行,否则会返回权限不足错误。 - 32位程序在64位Windows系统下默认会被重定向到
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node路径,如需访问64位原生注册表,需要在打开/创建Key的权限参数中追加KEY_WOW64_64KEY标志。
内容的提问来源于stack exchange,提问作者Max Buridant
相关产品推荐
相关产品推荐

