【问题标题】:RegQueryValueEx, need some assistanceRegQueryValueEx,需要一些帮助
【发布时间】:2016-03-17 03:50:49
【问题描述】:

编码新手,欢迎提出任何建议。

这就是我想要做的:

1) 在 HKLM 中打开运行键

2) 阅读我制作的名为“Test”的 REG_SZ。

3) 读取“测试”的数据

4) 如果找到“此数据”,则删除密钥。

5) 关闭钥匙。

我做错了什么?

#include <iostream>
#include <Windows.h>


using namespace std;


int main() {
char value[1024];
DWORD value_length = 1024;
DWORD keytype = REG_SZ;
HKEY hk;
LONG result;
LONG result2;
char response;
cout << "Would you like to scan? (Y) or (N)";
cin >> response;
if (response == 'Y')
{
    result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_ALL_ACCESS | KEY_WOW64_64KEY, &hk);
        if ( result == ERROR_SUCCESS) {

            result2 = RegQueryValueEx(hk, ("Test"), NULL, &keytype, (LPBYTE)&value, &value_length);
            if (result2 == ERROR_ACCESS_DENIED) {
                cout << "Access Denied." << endl;
                RegCloseKey(hk);
                system("pause");

            }
            else if (result2 == ERROR_MORE_DATA) {
                cout << "lpData buffer is too small to receive the data." << endl;
                RegCloseKey(hk);
                system("pause");
            }
            else if (result2 == ERROR_FILE_NOT_FOUND) {
                cout << "Value does not exist for LpValueName." << endl;
                RegCloseKey(hk);
                system("pause");
            }

            else if (result2 == ERROR_SUCCESS) { //If the function succeeds, the return value is ERROR_SUCCESS.
                cout << "The value read from the registry is: " << value << endl;
                RegCloseKey(hk);
                system("pause");

            }
        }
        else if (result == ERROR_FILE_NOT_FOUND)
        {
            cout << "Key not found." << endl;
            system("pause");
        }
    }

    else if (response == 'N')
    {
        return 0;
        system("pause");
    }
}

【问题讨论】:

  • 你试过cout &lt;&lt; value &lt;&lt; '\n';看看它打印了什么吗?
  • 到底是什么问题?你已经知道如何读取数据,你已经在做。数据在您的 value[] 数组中。 RegQueryValueEx() 的返回值(您将忽略)将告诉您该值是否存在于打开的密钥中,value_length 将告诉您读取了多少字节。然后你只需要扫描value[]的内容,比如strncmp()strstr()等,看你的需要。如果您找到匹配项,请致电RegDeleteValue()
  • 在不相关的注释中,ERROR_SUCCESS 是一个误导性名称!
  • 您正在测试 RegOpenKeyEx 是否失败 (!= ERROR_SUCCESS),这意味着如果成功,您将不会从注册表中读取值并且 value 未初始化。
  • 更新问题中的代码,不要将其粘贴到评论中。如果它“失败”,请解释如何它失败了。

标签: c++ winapi registry


【解决方案1】:

您检查RegOpenKeyEx 返回值的逻辑是相反的。仅在返回 ERROR_SUCCESS 时继续。

if (RegOpenKeyEx(...) == ERROR_SUCCESS)
    .... // go ahead

您没有检查RegQueryValueEx 的返回值中的错误。它可能失败了。

它可能会失败,因为您没有考虑registry redirector。您正试图从注册表的 64 位视图中读取,但您有一个 32 位进程,并且重定向器意味着您看到的是 32 位视图。将KEY_WOW64_64KEY 标志传递给RegOpenKeyEx 以从64 位视图中读取。

请注意,从注册表 API 函数返回的字符串不能以空值结尾。使用value_length 中返回的值显式添加空终止符。

当您获得读取排序键的代码时,您希望将其删除。因为它在HKLM 之下,所以您的进程必须以管理员权限运行。您将必须使用具有足够权限的访问标志来删除,换句话说,它比KEY_READ 更强大。

顺便说一句,由于您始终选择使用 ANSI API,因此使用 TEXT 宏会产生误导。就个人而言,我会选择 Unicode API。

【讨论】:

  • 好吧,我想我改写对了。我一直在网上使用很多教程来解决这个问题。我目前不需要 64Key,因为它不在 WOW6432Node 中。它位于 HKLM\Software\Microsoft\Windows\Current Version\Run 中。 REG_SZ 被命名为“测试”。重新编译后,无论我选择什么选项,现在我的程序都会退出。
  • WOW6432Node 是 32 位视图。您需要从 64 位视图中读取。就像我说的。你需要调试。
  • 你必须更加专注于我所说的话。现在你要求 KEY_ALL_ACCESS 但我敢打赌你没有管理员权限。无论如何,调试是您缺少的技能。当函数失败时,它们会返回错误代码。你不检查他们。
  • 感谢您的帮助大卫,我想我可能会解决这个问题。现在我正在使用指定的密钥,并且在调用 RegOpenKey 时返回 ERROR_FILE_NOT_FOUND。另外,我如何 null 终止它?
  • 现在您的问题编辑使我的答案无效。这不是很酷。请停止更改问题。我不想再花时间帮助你了。