【问题标题】:RegEnumValue crashes applicationRegEnumValue 使应用程序崩溃
【发布时间】:2012-05-08 21:20:19
【问题描述】:

我目前正在学习如何使用 c++ 处理注册表。我制作了一个应用程序,应该查看某个键中的某个值是否存在。但是,应用程序一到达 RegEnumValue() 就会崩溃。有什么想法可能是什么问题?

代码:

#include <iostream>
#include <windows.h>
#include <Psapi.h>

using namespace std;

bool registerKeyExists(char* key, char* subkey);

int main()
{
    while(true){
        if(registerKeyExists("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", "SynTPEnh")){
            return 0;
        }
    }

    return 0;
}

bool registerKeyExists(char* key, char* subkey){
    HKEY keyEnum;
    if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &keyEnum) == ERROR_SUCCESS){
        char* valueName;
        DWORD valueSize = 100;
        DWORD cbName;
        FILETIME lastFiletime;
        DWORD i = 0;
        DWORD returnCode = ERROR_SUCCESS;
        while(returnCode == ERROR_SUCCESS){
            cout << "This show!" << endl;
            returnCode = RegEnumValue(keyEnum, i, valueName, &valueSize, NULL, NULL, NULL, NULL);
            cout << "This doesn't show!" << endl;
            if(valueName == subkey)
                return true;
            i++;
        }
    }
    return false;
}

【问题讨论】:

    标签: c++ winapi registry


    【解决方案1】:

    您没有为值的名称提供任何空格。您正在将未初始化的指针 valueName 传递给 RegEnumValue(),它会拒绝(显然是通过使您的应用程序崩溃)。请尝试以下方法:

    char valueName[100];
    DWORD valueSize = sizeof(valueName);
    

    这会为返回的值名称保留 100 个字符。

    您还需要使用strcmp() 而不是== 来测试字符串值:

    if (strcmp(valueName, subkey) == 0) ...
    

    【讨论】:

    • 别忘了比较尺寸! strlen(valueName) == strlen(subkey)
    • @KlemensBaum:使用strcmp() 时无需比较大小。如果长度不同,strcmp() 不会返回 0。
    【解决方案2】:

    来自 RegEnumValue() 的 SDK 文档:

    LONG WINAPI RegEnumValue(
      __in         HKEY hKey,
      __in         DWORD dwIndex,
      __out        LPTSTR lpValueName,         // <=== here
      __inout      LPDWORD lpcchValueName,
      __reserved   LPDWORD lpReserved,
      __out_opt    LPDWORD lpType,
      __out_opt    LPBYTE lpData,
      __inout_opt  LPDWORD lpcbData
    );
    

    注意 lpValueName 参数上的 __outSAL 注释。这意味着“将通过您提供的指针写入”。特别是,写下 SDK 文章其余部分中记录的值的名称。

    问题是,您没有传递指向可写入内存的初始化指针。一个足以接收字符串的 TCHAR[] 数组,如下一个参数 lpcchValueName 所示。你让它未初始化。谎称你为数组分配了 100 个字符。

    卡布姆。

    【讨论】:

      猜你喜欢
      • 2017-11-10
      • 2012-08-18
      • 2012-02-12
      • 2014-03-18
      • 2014-11-14
      • 2018-12-05
      • 2012-08-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多