枚举注册表子项

时间:2011-11-15 07:19:34

标签: winapi registry

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

我甚至没有得到achValue

非常感谢

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

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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

我的一些钥匙没有被查看&#34;通过RegEnumKeyEx()。 我花了半天时间才明​​白我的问题是32/64位问题。

  

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

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