我正在使用Visual C ++ 2008 Express创建一个C ++程序,它从注册表中获取特定应用程序的路径,显示已安装的列表,允许用户选择一个进行配置,然后启动所选应用程序。
该程序应该使用RegGetValue(来自windows.h)检索(当前)三个应用程序的路径。
虽然它适用于应用程序n°1和3,但它以app n°2失败。
处理注册表的源代码部分可在Pastebin上使用:http://pastebin.com/9X2hjGqh。
当我添加一个cout以获得函数的返回时,我得到错误n°234(ERROR_MORE_DATA)。
RegGetValue语法:
LONG WINAPI RegGetValue(
_In_ HKEY hkey,
_In_opt_ LPCTSTR lpSubKey,
_In_opt_ LPCTSTR lpValue,
_In_opt_ DWORD dwFlags,
_Out_opt_ LPDWORD pdwType,
_Out_opt_ PVOID pvData,
_Inout_opt_ LPDWORD pcbData
);
此处完整参考:http://msdn.microsoft.com/en-us/library/ms724875(v=VS.85).aspx
答案 0 :(得分:0)
ERROR_MORE_DATA
表示您传递给RegGetValue
的其中一个缓冲区不足以存储您RegGetValue
提供给您的数据。当你得到这个退出代码时,你需要循环并重新分配这里提供的缓冲区。
例如:
LONG result = ERROR_MORE_DATA;
DWORD dataLength = /* some reasonable default size */ 255;
unique_ptr<char[]> buffer;
while (result == ERROR_MORE_DATA)
{
buffer.reset(new char[dataLength]);
result = RegGetValueW(
hKey,
L"Subkey",
L"Value",
0,
nullptr,
buffer.get(),
&dataLength
);
}
if (result != ERROR_SUCCESS)
{
// Handle the error
}
答案 1 :(得分:0)
有一点突出的是你这么做的所有电话:
RegGetValue(hKey, NULL, "PATH", RRF_RT_ANY, NULL, (PVOID)&ValueBuffer, &BufferSize);
请注意,最后一个参数是&BufferSize
。这是[in, out]
参数。在进入之前将其设置为缓冲区的大小,并将值更改为在出路时读入缓冲区的字符数。这就是docs关于RegGetValue(以及其他类似的Reg)函数的说法:
pcbData [in,out,optional] 指向变量的指针,该变量指定pvData参数指向的缓冲区大小(以字节为单位)。函数返回时,此变量包含复制到pvData的数据大小。
因此,当您调用RegGetValue时,它从8192(BUFFER
)开始,但在第一次调用后,它被读取的字符数覆盖。
在每次调用传递&amp; BufferSize的RegGetValue之前,你应该这样做:
BufferSize = BUFFER
我也注意到你有:
#define BUFFER 8192
char ValueBuffer[255];
DWORD BufferSize = BUFFER;
您不应该将ValueBuffer
设置为至少ValueBuffer[BUFFER]
而不是ValueBuffer[255]
吗?
同样,您的代码只支持8192字节缓冲区。如果注册表中的Value键长于该值,则返回ERROR_MORE_DATA
。我假设您的代码没有预期8192之外的任何内容。您可以使用RegQueryInfoKey并提前动态分配足够的空间来确定Value键的前端大小。