在RegQueryValueEx之后lpData没有得到值

时间:2013-12-02 07:59:19

标签: c++ registry

我不确定问题出在哪里。 我有一个演示代码从注册表中获取值:

using namespace std;

typedef struct REGKEYS
{
    HKEY hKey;
    LPCTSTR subKey;
    LPCTSTR value;
    LPCTSTR name;
    LPCTSTR file;
    LPCTSTR tag;
} REGKEYS;

REGKEYS regkeys = {HKEY_LOCAL_MACHINE,"Software\\Internet Download Manager", "Serial", "IDM", NULL, NULL};
HKEY hKey;
LPBYTE szDataBuf;
DWORD dwSize;

int _tmain(int argc, _TCHAR* argv[])
{
    RegOpenKeyEx(regkeys.hKey, regkeys.subKey, 0, KEY_READ, &hKey);
    RegQueryValueEx(hKey, regkeys.value, NULL, NULL, szDataBuf, &dwSize);
    int lerr = GetLastError();

    system("pause");
    return 0;
}

调试时,我看到regkeys.hKey没有指向任何东西(它需要指向“HKEY_LOCAL_MACHINE”,是吗?)。 而szDataBuf是空的。 (GetLastError()对我没有帮助 - 它返回0)

有人告诉我问题在哪里以及如何解决?

EDIT2:

我将代码编辑为:

int _tmain(int argc, _TCHAR* argv[])
{
    DWORD dwSize = 0;
    RegOpenKeyEx(regkeys.hKey, regkeys.subKey, 0, KEY_READ, &hKey);

    RegQueryValueEx(hKey, regkeys.value, NULL, NULL, NULL, &dwSize);
    char *szDataBuf = new char(dwSize);
    RegQueryValueEx(hKey, regkeys.value, NULL, NULL, (LPBYTE)szDataBuf, &dwSize);

    delete[] szDataBuf;
    system("pause");
    return 0;
}

我调试并看到szDataBuf得到正确的值,但我的程序中断并得到警告:警告C4244:'初始化':从'DWORD'转换为'char',可能会丢失数据。

1 个答案:

答案 0 :(得分:3)

首先,您的错误检查代码不正确。注册表函数都返回Win32错误代码。您需要注意它们并检查错误。

要明确,GetLastError没有用,因为这些功能不会调用SetLastError。它们直接返回错误代码。您必须仔细阅读文档。 Win32的不同部分进行错误处理的方式通常存在细微差别。

更新后的问题中的代码更好,但仍无法检查RegOpenKeyEx调用中的错误。

现在,除此之外,您实际上并没有正确地调用RegQueryValueEx。您尚未初始化dwSize,但尚未分配szDataBuf。由于这些是全局变量,因此它们将初始化为零。因此,如果值存在,您对RegQueryValueEx的调用确实会成功。但是你不能指望任何值到达缓冲区,因为你没有分配缓冲区。您正在将NULL传递给lpData参数。

所以,分配一个缓冲区。例如:

char szDataBuf[128];

初始化dwSize

DWORD dwSize = sizeof(szDataBuf);

然后您对RegQueryValueEx的电话应为

int lerr = RegQueryValueEx(hKey, regkeys.value, NULL, NULL, 
    (LPBYTE)szDataBuf, &dwSize);

虽然您可能希望动态分配缓冲区:

dwSize = 0;
int lerr = RegQueryValueEx(hKey, regkeys.value, NULL, NULL, NULL, &dwSize);
// check lerr here
vector<char> szDataBuf(dwSize);
int lerr = RegQueryValueEx(hKey, regkeys.value, NULL, NULL, 
    (LPBYTE)&szDataBuf[0], &dwSize);
// check lerr here

您也可以考虑在此避免使用全局变量。你使用的所有变量都会比当地人更有意义。