C++读取注册表SOFTWARE键时出现随机ASCII字符问题求助
读取Windows注册表SOFTWARE键时出现随机ASCII字符的问题
我用C++读取Windows注册表时,访问SOFTWARE键会出现随机ASCII字符,但访问其他键功能正常。试过切换到HARDWARE键,但该键下的值重启后会丢失,SOFTWARE键的异常问题仍存在,实际读取结果显示为乱码而非预期值。
我的代码如下:
#include <iostream> #include <cctype> #include <windows.h> //Basic registry tweaking code made by Przemyslaw Zaworski in 2017 //to store passwords std::string registry_read (LPCTSTR subkey,LPCTSTR name,DWORD type) { HKEY key; TCHAR value[255]; DWORD value_length = 255; RegOpenKey(HKEY_LOCAL_MACHINE,subkey,&key); RegQueryValueEx(key,name, NULL, &type, (LPBYTE)&value, &value_length); RegCloseKey(key); return value; } void registry_write (LPCTSTR subkey,LPCTSTR name,DWORD type,const char* value) { HKEY key; RegOpenKey(HKEY_LOCAL_MACHINE,subkey,&key); RegSetValueEx(key, name, 0, type, (LPBYTE)value, strlen(value)*sizeof(char)); RegCloseKey(key); } int main(){ //TODO: fix this what the std::string text = registry_read("SOFTWARE\\FilePasser","Password",REG_SZ); //Read the registry value std::cout << text << std::endl; std::string input; return 0; }
问题根源
- 字符集不匹配:代码混用了ANSI和Unicode版本的注册表API。
LPCTSTR在Unicode编译环境下对应const wchar_t*,但registry_write用const char*传入ANSI字符串,读取时用TCHAR(即wchar_t)解析,导致解码错误出现乱码。 - 无错误检查:
RegOpenKey、RegQueryValueEx等API可能调用失败(比如权限不足、键不存在),未处理错误会导致后续操作基于无效句柄,产生意外结果。 - 注册表重定向:如果是32位程序,访问
HKEY_LOCAL_MACHINE\SOFTWARE会被系统重定向到HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node,若值实际写入64位路径,读取时会拿到错误内容。
修复方案
1. 统一字符集(推荐用Unicode)
Windows系统原生支持Unicode,改用后缀为W的Unicode版本API,对应wchar_t和std::wstring:
2. 添加错误检查
每个注册表API调用后检查返回值,确保操作有效后再执行后续步骤。
3. 处理注册表重定向
通过RegOpenKeyEx指定KEY_WOW64_64KEY(访问64位注册表)或KEY_WOW64_32KEY(访问32位注册表)标志,避免重定向干扰。
修复后的代码示例
#include <iostream> #include <string> #include <windows.h> std::wstring registry_read(const wchar_t* subkey, const wchar_t* name) { HKEY key; // 打开64位注册表路径,添加错误检查 LONG result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, subkey, 0, KEY_READ | KEY_WOW64_64KEY, &key); if (result != ERROR_SUCCESS) { return L""; } wchar_t value[255]; DWORD value_length = sizeof(value); DWORD type = REG_SZ; result = RegQueryValueExW(key, name, NULL, &type, (LPBYTE)value, &value_length); RegCloseKey(key); if (result == ERROR_SUCCESS && type == REG_SZ) { return value; } return L""; } void registry_write(const wchar_t* subkey, const wchar_t* name, const wchar_t* value) { HKEY key; // 不存在则创建键,指定64位路径 LONG result = RegCreateKeyExW(HKEY_LOCAL_MACHINE, subkey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_WOW64_64KEY, NULL, &key, NULL); if (result != ERROR_SUCCESS) { return; } // 包含字符串终止符的长度,确保数据完整 DWORD data_size = (wcslen(value) + 1) * sizeof(wchar_t); RegSetValueExW(key, name, 0, REG_SZ, (LPBYTE)value, data_size); RegCloseKey(key); } int main() { std::wstring text = registry_read(L"SOFTWARE\\FilePasser", L"Password"); std::wcout << text << std::endl; // 示例写入:registry_write(L"SOFTWARE\\FilePasser", L"Password", L"your_password_here"); return 0; }
内容的提问来源于stack exchange,提问作者O0JJC
相关产品推荐
相关产品推荐

