首页 文章

枚举注册表子项

提问于
浏览
0

来自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,NULL,NULL,NULL);

我甚至没有得到achValue

非常感谢

PD使用Windows 7 64位visual studio 2010终极版

3 回答

  • 2

    四个 NULL 值中的第一个是 lpReserved ,必须设置为NULL .

    第二个是 lpType ,你应该能够自己获得那个 .

    第三个和第四个是配对的,必须设置为NULL或两者都设置为非NULL . 它们的功能类似于 achValuecchValue ,其中第一个是接收数据的缓冲区,第二个是指向必须首先具有缓冲区大小的大小的指针,然后用数据大小填充 .

    以下代码适用于我的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

    为什么不使用.net框架类来使用注册表?

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

  • 1

    为了帮助其他人在枚举注册表子项时遇到问题:

    我的一些密钥没有被RegEnumKeyEx()“查看” . 我花了半天时间才明白我的问题是32/64位问题 .

    默认情况下,在WOW64上运行的32位应用程序访问32位注册表视图,而64位应用程序访问64位注册表视图 .

    阅读MSDN : Alternate Registry View以了解如何正确设置samDesired参数 .

相关问题