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 读取
十分感谢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 ); 第二个参数是需要指定键(值)名称的。它该如何获得。
它分有:
case REG_SZ:
case REG_EXPAND_SZ:
case REG_MULTI_SZ:
case REG_DWORD:
case REG_DWORD_BIG_ENDIAN:
case REG_BINARY:这些类型,需要根据类型不同分别用 RegQueryValueEx 读取
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
);
第二个参数是需要指定键(值)名称的。它该如何获得。
/*==============================================================================================
* 函数名: 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(®Value, 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);
}
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_”如何解释我还不太明白。
_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相对应也是同上。