Перечисление подразделов реестра - PullRequest
0 голосов
/ 15 ноября 2011

от msdn.microsoft.com - Перечисление подразделов реестра:

http://msdn.microsoft.com/En-US/library/ms724256.aspx

// QueryKey - Enumerates the subkeys of key and its associated values.
//     hKey - Key whose subkeys and values are to be enumerated.

#include <windows.h>
#include <stdio.h>
#include <tchar.h>

#define MAX_KEY_LENGTH 255
#define MAX_VALUE_NAME 16383

void QueryKey(HKEY hKey) 
{ 
    TCHAR    achKey[MAX_KEY_LENGTH];   // buffer for subkey name
    DWORD    cbName;                   // size of name string 
    TCHAR    achClass[MAX_PATH] = TEXT("");  // buffer for class name 
    DWORD    cchClassName = MAX_PATH;  // size of class string 
    DWORD    cSubKeys=0;               // number of subkeys 
    DWORD    cbMaxSubKey;              // longest subkey size 
    DWORD    cchMaxClass;              // longest class string 
    DWORD    cValues;              // number of values for key 
    DWORD    cchMaxValue;          // longest value name 
    DWORD    cbMaxValueData;       // longest value data 
    DWORD    cbSecurityDescriptor; // size of security descriptor 
    FILETIME ftLastWriteTime;      // last write time 

    DWORD i, retCode; 

    TCHAR  achValue[MAX_VALUE_NAME]; 
    DWORD cchValue = MAX_VALUE_NAME; 

    // Get the class name and the value count. 
    retCode = RegQueryInfoKey(
        hKey,                    // key handle 
        achClass,                // buffer for class name 
        &cchClassName,           // size of class string 
        NULL,                    // reserved 
        &cSubKeys,               // number of subkeys 
        &cbMaxSubKey,            // longest subkey size 
        &cchMaxClass,            // longest class string 
        &cValues,                // number of values for this key 
        &cchMaxValue,            // longest value name 
        &cbMaxValueData,         // longest value data 
        &cbSecurityDescriptor,   // security descriptor 
        &ftLastWriteTime);       // last write time 

    // Enumerate the subkeys, until RegEnumKeyEx fails.

    if (cSubKeys)
    {
        printf( "\nNumber of subkeys: %d\n", cSubKeys);

        for (i=0; i<cSubKeys; i++) 
        { 
            cbName = MAX_KEY_LENGTH;
            retCode = RegEnumKeyEx(hKey, i,
                     achKey, 
                     &cbName, 
                     NULL, 
                     NULL, 
                     NULL, 
                     &ftLastWriteTime); 
            if (retCode == ERROR_SUCCESS) 
            {
                _tprintf(TEXT("(%d) %s\n"), i+1, achKey);
            }
        }
    } 

    // 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); 
            } 
        }
    }
}

void __cdecl _tmain(void)
{
   HKEY hTestKey;

   if( RegOpenKeyEx( HKEY_CURRENT_USER,
        TEXT("SOFTWARE\\Microsoft"),
        0,
        KEY_READ,
        &hTestKey) == ERROR_SUCCESS
      )
   {
      QueryKey(hTestKey);
   }

   RegCloseKey(hTestKey);
}

как я могу изменить этот код по адресу:

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); 
            } 

для вывода на консоль всех значений, которые может вернуть функция RegEnumValue, функция в MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/ms724865%28v=vs.85%29.aspx я тоже хочу вывести эти переменные:

  __out        LPTSTR lpValueName,
  __inout      LPDWORD lpcchValueName,
  __out_opt    LPDWORD lpType,
  __out_opt    LPBYTE lpData,
  __inout_opt  LPDWORD lpcbData

Я пробовал разные вещи, но каждый раз, когда я меняю любой из NULL var из эта функция:

retCode = RegEnumValue (hKey, i, achValue, & CchValue, НОЛЬ, НОЛЬ, НОЛЬ, NULL);

я даже не могу получить значение

спасибо большое

PD с использованием Windows 7 64 бит Visual Studio 2010 Ultimate

Ответы [ 3 ]

2 голосов
/ 15 ноября 2011

Почему бы не использовать классы .net framework для работы с реестром?

http://msdn.microsoft.com/en-us/library/df4afx57%28v=vs.80%29.aspx

1 голос
/ 17 ноября 2011

Первое из четырех значений NULL равно lpReserved и должно быть установлено в NULL.

Второй - lpType, и вы сможете получить его самостоятельно.

Третий и четвертый парные и должны быть установлены в NULL или оба не NULL. Они функционируют так же, как achValue и cchValue, где первый - это буфер для получения данных, а второй - указатель на размер, который должен сначала иметь размер буфера, а затем заполняться размером данных. .

На моем компьютере с Vista работает следующий код:

        const DWORD maxValueBytes=300;
        BYTE valueBytes[maxValueBytes];
        DWORD valueSize=maxValueBytes;
        DWORD valueType=0;
        cchValue = MAX_VALUE_NAME;  
        achValue[0] = '\0';  
        retCode = RegEnumValue(hKey, i,  
            achValue,  
            &cchValue,  
            NULL,  
            &valueType, 
            valueBytes, 
            &valueSize); 

        if (retCode == ERROR_SUCCESS )  
        {  
            _tprintf(TEXT("(%d) %s (%d - %d bytes)\n"), i+1, achValue,valueType,valueSize);  
            switch (valueType) {
                case REG_BINARY:
                    _tprintf(TEXT("   The value is binary (0x%X, 0x%X, 0x%X ...)\n"),valueBytes[0],valueBytes[1],valueBytes[2]);
                    break;
                case REG_DWORD:
                //case REG_DWORD_LITTLE_ENDIAN:
                    _tprintf(TEXT("   The value is a DWORD (%d)\n"),*(DWORD *)valueBytes);
                    break;
                case REG_DWORD_BIG_ENDIAN:
                    _tprintf(TEXT("   The value is a DWORD (big endian) (%d)\n"),(valueBytes[0]<<24)|(valueBytes[1]<<16)|(valueBytes[2]<<8)|valueBytes[3]);
                    break;
                case REG_EXPAND_SZ:
                case REG_SZ:
                    _tprintf(TEXT("   The value is a string\n"));
                  break;
                case REG_LINK:
                    _tprintf(TEXT("   The value is a link\n"));
                  break;
                case REG_MULTI_SZ:
                    _tprintf(TEXT("   The value is a multi-string\n"));
                  break;
                case REG_NONE:
                    _tprintf(TEXT("   There is no spoon... sorry, value\n"));
                  break;
                case REG_RESOURCE_LIST:
                    _tprintf(TEXT("   The value is a resource list\n"));
                  break;
                default:
                    _tprintf(TEXT("   Unknown value type\n"));
                  break;
            }
        }
        else
        {
            _tprintf(TEXT("error reading value %d - %d\n"),i+1,retCode);
        }
0 голосов
/ 01 сентября 2015

Чтобы помочь другим людям, имеющим проблемы с перечислением подразделов реестра:

Некоторые из моих ключей не были «просмотрены» RegEnumKeyEx (). Я потратил примерно полдня, чтобы понять, что моя проблема была 32/64-битной.

По умолчанию 32-разрядное приложение, работающее на WOW64, получает доступ к 32-разрядному представлению реестра, а 64-разрядное приложение обращается к 64-разрядному представлению реестра.

Чтение MSDN: альтернативный просмотр реестра , чтобы узнать, как правильно установить параметр samDesired .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...