本帖最后由 VisualEleven 于 2014-02-21 18:22:01 编辑

解决方案 »

  1.   

    RegEnumValue 这里枚举出的键值不能都当作REG_SZ处理,
    它分有:
    case REG_SZ:
    case REG_EXPAND_SZ:
    case REG_MULTI_SZ:
    case REG_DWORD:
    case REG_DWORD_BIG_ENDIAN:
    case REG_BINARY:这些类型,需要根据类型不同分别用 RegQueryValueEx 读取
      

  2.   

    十分感谢xiaoc1026的回复,给了我很多的启发。但是我还有一些个不明白的地方希望能够得到启迪:
    1、为什么我的第一张图(调试后运行的结果图)中编号为1、2、3的键名没有显示出来,只有0、4、5显示出来了?
    2、如果得不到键名称,那么RegQueryValueEx这个函数是不是就不能够使用了呢?下面是我查询到RegQueryValueEx这个函数的说明:
    RegQueryValueEx FunctionRetrieves the type and data for the specified value name associated with an open registry key.To ensure that any string values (REG_SZ, REG_MULTI_SZ, and REG_EXPAND_SZ) returned are null-terminated, use the RegGetValue function.
    LONG WINAPI RegQueryValueEx(
      __in          HKEY hKey,
      __in          LPCTSTR lpValueName,
      LPDWORD lpReserved,
      __out         LPDWORD lpType,
      __out         LPBYTE lpData,
      __in_out      LPDWORD lpcbData
    );
    第二个参数是需要指定键(值)名称的。它该如何获得。
      

  3.   

    另外注册表中Run下的类型都是REG_SZ啊,都一样的东西为什么不能都显示出来?
      

  4.   

    你看下能不能帮到你~
    /*============================================================================================== 
    * 函数名: GetValue
    * 参数:
    * vecRegValues [vector][OUT],存储数据项名称和数值
    * 功能描述:获取子键下所有数据项和数值
    * 返回值:  存在返回TRUE,否则返回FALSE
    ==============================================================================================*/
    DWORD g_dwIndex = 0;
    BOOL CReg::GetValues(LPCTSTR lpSubKey, LPCTSTR lpIncludedValueNames, DWORD dwIndex, map<string, KEYVALUE>& mapValues)
    {
    g_dwIndex = dwIndex;
    TCHAR szValueName[MAX_REG_NAME_LEN + 1] = {0x00}; 
    DWORD dwValueNameLen = MAX_REG_NAME_LEN;
    DWORD dwType = 255;
    DWORD dwErrorCode = ERROR_SUCCESS;
    BYTE  cbMultiValue[MAX_REG_VALUE_LEN + 1] = {0x00};
    DWORD dwValue = 0; HKEY hKey;
    m_dwErrorCode = (DWORD)::RegOpenKeyEx (m_hRootKey, lpSubKey, 0L, KEY_ALL_ACCESS, &hKey);
    if (ERROR_SUCCESS != m_dwErrorCode)
    {
    return FALSE;
    } while (ERROR_NO_MORE_ITEMS != dwErrorCode && ERROR_INVALID_HANDLE != dwErrorCode)
    {
    memset(szValueName, 0x00, sizeof(szValueName));
    dwErrorCode = (DWORD)::RegEnumValue(
    hKey, 
    g_dwIndex, 
    szValueName, 
    &dwValueNameLen, 
    NULL, 
    &dwType,    // &dwType, 
    NULL,    // &bData, 
    NULL);   // &bcData 
    if (ERROR_SUCCESS == dwErrorCode)
    {
    if (-1 == CUtilityEx::FindInString(szValueName, lpIncludedValueNames, ","))
    {
    g_dwIndex++;
    continue;
    } KEYVALUE regValue;
    memset(&regValue, 0x00, sizeof(KEYVALUE));
    regValue.dwType = dwType;
    string strValueName = szValueName;
    string strRet= "";
    DWORD dwReturnType = dwType;
    DWORD dwReturnSize = 0;
    switch(dwType)
    {
    case REG_SZ:
    case REG_EXPAND_SZ:
    dwReturnSize = MAX_REG_VALUE_LEN;
    if (Read(lpSubKey, szValueName, dwReturnType, (BYTE*)regValue.szValue, dwReturnSize))
    {
    mapValues[strValueName]  = regValue;
    }
    else
    {
    m_dwErrorCode = ::GetLastError();
    }
    break; case REG_MULTI_SZ:
    dwReturnSize = MAX_REG_VALUE_LEN;
    if (ReadMultiSZ(lpSubKey, szValueName, regValue.szValue, dwReturnSize))
    {
    mapValues[strValueName]  = regValue;
    }
    else
    {
    m_dwErrorCode = ::GetLastError();
    }
    break; case REG_DWORD:
    case REG_DWORD_BIG_ENDIAN:
    dwReturnSize = sizeof(DWORD);
    if (Read(lpSubKey, szValueName, dwReturnType, (BYTE*)&dwValue, dwReturnSize))
    {
    _stprintf(regValue.szValue, _T("%u"), dwValue);
    mapValues[strValueName] = regValue;
    }
    else
    {
    m_dwErrorCode = ::GetLastError();
    }
    break; case REG_BINARY:
    dwReturnSize = MAX_REG_VALUE_LEN;
    if (Read(lpSubKey, szValueName, dwReturnType, cbMultiValue, dwReturnSize))
    {
    if (CUtilityEx::Bytes2String(cbMultiValue, ",", dwReturnSize, strRet))
    {
    _tcsncpy(regValue.szValue, strRet.c_str(), min(MAX_REG_VALUE_LEN, strRet.length()));
    mapValues[strValueName] = regValue;
    }
    }
    else
    {
    m_dwErrorCode = ::GetLastError();
    }
    break; default:
    break;
    }
    } if (ERROR_MORE_DATA == dwErrorCode)
    {
    GetValues(lpSubKey, lpIncludedValueNames, g_dwIndex, mapValues);
    }
    g_dwIndex++;
    } if (hKey)
    {
    ::RegCloseKey(hKey);
    } return (mapValues.size() > 0);
    }
    BOOL CReg::Read(LPCTSTR lpSubKey, LPCTSTR lpValueName, DWORD& dwType, BYTE* lpValue, DWORD& dwSize)
    {
    memset(m_szOperation, 0x00, sizeof(m_szOperation));
    _tcscpy(m_szOperation, _T("ReadInt: RegQueryValueEx")); HKEY hKey;
    m_dwErrorCode = (DWORD)::RegOpenKeyEx (m_hRootKey, lpSubKey, 0L, KEY_ALL_ACCESS, &hKey);
    if (ERROR_SUCCESS != m_dwErrorCode)
    {
    return FALSE;
    } m_dwErrorCode = (DWORD)::RegQueryValueEx (hKey, lpValueName, NULL, &dwType, lpValue, &dwSize); if (hKey)
    {
    ::RegCloseKey(hKey);
    } return (ERROR_SUCCESS == m_dwErrorCode);
    }
      

  5.   

    我找到方法让注册表中启动项完全显示了,就是在代码47行的后面加上两行:
    dwBufferSize=MAXBYTE;
    dwKeySize=MAXBYTE;
    给这两个变更重新赋值为MAXBYTE,这样就行了。我又看了一下关于枚举注册表值函数的内容:
    LONG WINAPI RegEnumValue(
      _In_         HKEY hKey,
      _In_         DWORD dwIndex,
      _Out_        LPTSTR lpValueName,
      _Inout_      LPDWORD lpcchValueName,
      _Reserved_   LPDWORD lpReserved,
      _Out_opt_    LPDWORD lpType,
      _Out_opt_    LPBYTE lpData,
      _Inout_opt_  LPDWORD lpcbData
    );
    http://msdn.microsoft.com/en-us/library/ms724865(VS.85).aspx
    其中的第4、第8个参数就是被赋值为MAXBYTE的那两个变量。不过前面的那个“_Inout_”和“_Inout_opt_”如何解释我还不太明白。
      

  6.   

    IN 输入 OUT输出,这个参数可以输入输出。。
      

  7.   

    LONG WINAPI RegEnumValue(
       _In_         HKEY hKey,
       _In_         DWORD dwIndex,
       _Out_        LPTSTR lpValueName,
       _Inout_      LPDWORD lpcchValueName,
       _Reserved_   LPDWORD lpReserved,
       _Out_opt_    LPDWORD lpType,
       _Out_opt_    LPBYTE lpData,
       _Inout_opt_  LPDWORD lpcbData
     );
    还有:
    这个函数里面
    函数运行前,lpcchValueName地址中字符串的长度值一定要比lpValueName实际获得的字符串的长度要长,函数运行后lpcchValueName地址中改写保存成了lpValueName实际获得的字符串的长度,如果短了的话那么lpValueName就不会被函数写进去值而变为空字符串,所以每次函数运行后,要再给lpcchValueName负值为MAXBYTE
     lpcbData和 lpData相对应也是同上。