以下代码似乎无法可靠地执行,并且在不确定的时间之后它将在 RegEnumValue
函数中失败并显示错误代码 234。
我没有编写这段代码,我只是想调试它。我知道执行 RegEnumValue
然后删除 while 循环中的键存在问题。
我想首先弄清楚,为什么它会在看似随机的点上抛出这个 234 错误,因为它永远不会经过一致数量的循环迭代或类似的事情。
据我所见,它无法填充其名称缓冲区,但这个缓冲区对于它的用途来说绝不是太小,所以我不明白它怎么会失败??
有人可以请教如何摆脱 RegEnumValue 函数抛出的这个 234 错误吗?
HKEY key;
DWORD dw;
int idx;
char name[8192];
DWORD namesize=4096;
std::string m_path = "SOFTWARE\\Company\\Server 4.0";
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,m_path.c_str(),0,KEY_ALL_ACCESS,&key) == ERROR_SUCCESS)
{
bool error=false;
idx=0;
long result;
long delresult;
while (true)
{
result = RegEnumValue(key,idx,(char*)name,&namesize,NULL,NULL,NULL,NULL);
if (result == ERROR_SUCCESS && !error){
delresult = RegDeleteValue(key,name);
if (delresult != ERROR_SUCCESS)
error = true;
idx++;
}
else
{
break;
}
}
RegCloseKey(key);
}
最佳答案
您的代码中存在一些错误:
- RegEnumValue 的第 4 个参数(
namesize
) 是输入输出参数。因此,您必须将namesize
重置为sizeof(name)/sizeof(name[0])
(在使用char
类型的情况下,它是只是sizeof(name)
) 在while
循环内 在 RegEnumValue 的每次调用之前 .这是您程序中的主要错误。 - 如果您不想在任何时候有包含 32,767 个字符的缓冲区时出现
ERROR_MORE_DATA
错误。它是注册表值的名称的最大大小(请参阅 RegEnumValue 的文档)。 - 在
RegOpenKeyEx
中使用KEY_ALL_ACCESS
是不好的。我建议您将其更改为KEY_QUERY_VALUE | KEY_SET_VALUE
。这不是真正的错误,但它可能取决于您的环境。 - 最好使用所有这些函数的 UNICODE 版本来加快代码速度。
已更新:关于 UNICODE 版本的用法的小评论。 Intern Windows 使用 UNICODE 字符。所以使用非 Unicode 版本的 RegEnumValue si 更慢,因为在每次调用时,将分配一个新的 UICODE 内存块并将其转换为 ANSI/多字节。此外,如果您将使用无法在 Windows ANSI 代码页(中文、日文等)中转换的语言编写值名称,并且某些字符将被替换为“?” (请参阅 WideCharToMultiByte 的 WC_DEFAULTCHAR
标志),那么函数 RegDeleteValue
可能会失败,并显示错误代码,如“具有名称的值不存在”。
关于c++ - 注册表问题 - 使用 C++ 删除键/值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3582624/