使用RegEnumValue显示值名称和数据

时间:2013-10-09 00:48:36

标签: c++ winapi

我有以下代码:

#include <Windows.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


using namespace std;

int main(int argc, wchar_t*argv[])
{

    std::locale::global(std::locale("spanish"));


    /*Declaración de variables*/

    HKEY hKey = HKEY_CURRENT_USER;
    LPCTSTR lpSubKey = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU");
    DWORD ulOptions = 0;
    REGSAM samDesired = KEY_READ | KEY_WRITE;
    HKEY phkResult;
    DWORD dwIndex = 0;
    TCHAR lpValueName[16383];
    DWORD lpcchValueName = 16383;
    LPTSTR lpData="";

    long OpenK = RegOpenKeyEx(hKey, lpSubKey, ulOptions, samDesired, &phkResult);

    if (OpenK == ERROR_SUCCESS)
    {
        long R = RegEnumValue(phkResult, dwIndex, lpValueName, &lpcchValueName, NULL, NULL,(LPBYTE)lpData, NULL);


        if (R == ERROR_SUCCESS)
        {
            cout << "The value and data is: \n" << lpValueName << ": " << lpData << endl;
            //printf(TEXT("(%d) %s\n"), lpValueName);
        }
        else
            cout << "Error: " << R << endl;

    }
    else if (OpenK == ERROR_FILE_NOT_FOUND)
    {
        cout << "La sub-clave RunMRU no existe." << endl;
    }
    else if (OpenK == ERROR_ACCESS_DENIED)
    {
        cout << "Acceso denegado al abrir la sub-clave RunMRU." << endl;
    }
    else
    {
        cout << "Error al abrir la clave de registro. Código: " << OpenK << endl;

    }


    system("Pause");


}

我试图在第一个if中使用RegEnumValue来显示值名称及其数据(值和数据是:)但我只能显示值名称。

有没有办法做到这一点?我试图弄清楚如何使用lpData,但我不能因为我只收到错误87(参数不正确)或什么都没有(如果我改为设置NULL)。

3 个答案:

答案 0 :(得分:2)

您没有为RegEnumValue()提供合适的缓冲区来存储数据。

LPTSTR lpData="";

这只是一个字符串文字,大小最多为2个字节,无论如何几乎肯定不可写。您需要分配一个内存区域并将其传递给RegEnumValue()以读取每个值的数据。

您的第一步应该是使用RegQueryInfoKey()来确定最大数据值的大小。我向您展示了如何在previous answer中使用此函数来查询最大值名称的大小 - 过程是相同的。请参阅RegQueryInfoKey()的文档,找出哪个参数提供了数据大小。

一旦你知道最大的数据项有多大,就为它分配一个缓冲区:

void* pData = malloc(dwLargestValueSize);
// remember this buffer needs to be freed at the end with free()

然后将该缓冲区以及指示其大小的值传递给RegEnumValue()

您需要注意的其他事项是注册表值可以是不同类型 - REG_DWORDREG_SZ等,您从RegEnumValue()获取的数据是原始数据。 RegEnumValue()也可以返回一个表示数据类型的值,如果你要正确解释它,你也绝对需要检查一下。

答案 1 :(得分:1)

Here's the best example from MSDN。它有效。

问题中的代码:

long R = RegEnumValue(phkResult, dwIndex, lpValueName, &lpcchValueName, NULL, NULL,(LPBYTE)lpData, NULL);

传递 NULL 而不是(LPBYTE)lpData

适用于MSDN链接的解决方案:

// Enumerate the key values. 

if (cValues) 
{
    printf( "\nNumber of values: %d\n", cValues);

    for (i=0, retCode=ERROR_SUCCESS; i<cValues; i++) 
    { 
        cchValue = MAX_VALUE_NAME; 
        achValue[0] = '\0'; 
        retCode = RegEnumValue(hKey, i, 
            achValue, 
            &cchValue, 
            NULL, 
            NULL,
            NULL,
            NULL);

        if (retCode == ERROR_SUCCESS ) 
        { 
            _tprintf(TEXT("(%d) %s\n"), i+1, achValue); 
        } 
    }
}

答案 2 :(得分:0)

更改您的代码以将字符串值放入 lpData:

#define MAX_DATA_LENGTH 16383
char* lpData = new char[MAX_DATA_LENGTH];
DWORD lpDataLength = MAX_DATA_LENGTH;

RegEnumValue(phkResult, dwIndex, lpValueName, &lpcchValueName, NULL, NULL, (unsigned char*)lpData, &lpDataLength);