最近一个项目需要在注册表中搜索出相关信息并列举出来,参考了一下MSDN,整理了下面这个函数,直接用注册表的路径描述串(如:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows)指定要搜索的位置,并通过回调方式实时返回搜索结果,自己感觉还算好用吧。
基本就用API实现,加了注释,就不用多说明了,直接帖代码吧。
#include <windows.h>
#include <tchar.h>
#include <malloc.h>
#pragma warning (disable: 4996)
//-----------------------------------------------------------------------------------------------------------
// 函数:(注册表搜索(SearchInReg)回调函数类型定义)
// 功能:SearchInReg 函数在搜索过程中会实时调用该函数,以便调用者监控搜索进程状态。
// 参数:[in] bool - 是否找到
// [in] const TCHAR* - 结果字段(用于显示)
// [in] const TCHAR* - 被匹配部分的字段
// [in] const HKEY& - 当前键的句柄,用于在回调中对该键操作
// 返回:void
// 说明:
//-----------------------------------------------------------------------------------------------------------
typedef void (CALLBACK* LPONSEARCHPROC)(bool, // 是否找到
const TCHAR*, // 结果字段(用于显示)
const TCHAR*, // 被匹配部分的字段
const HKEY&); // 当前键的句柄,用于在回调中对该键操作
//-----------------------------------------------------------------------------------------------------------
// 函数:SearchInReg
// 功能:在注册表指定位置搜索某指定字符串。
// 参数:[in] LPONSEARCHPROC fnOnSearchProc - 搜索回调函数
// [in] const TCHAR* pszRegPath - 搜索路径(直接包含根键并支持缩写)
// [in] const TCHAR* pszSearchKey - 搜索关键字符串
// [in] bool isFuzzy = true - 是否采用模糊方式
// [in] bool isSearchKey = true - 是否搜索键
// [in] bool isSearchValueName = true - 是否搜索值名
// [in] bool isSearchValueData = true - 是否搜索值
// 返回:void
// 说明:若要统计搜索数量,请使用外部变量在回调函数中自行统计。
//-----------------------------------------------------------------------------------------------------------
void SearchInReg(LPONSEARCHPROC fnOnSearchProc, // 搜索回调函数
const TCHAR* pszRegPath, // 搜索路径(直接包含根键并支持缩写)
const TCHAR* pszSearchKey, // 搜索关键字符串
bool isFuzzy /* = true */, // 是否采用模糊方式
bool isSearchKey /* = true */, // 是否搜索键
bool isSearchValueName /* = true */, // 是否搜索值名
bool isSearchValueData /* = true */) // 是否搜索值
{
// 参数无效
if (NULL == pszRegPath || 0 == ::_tcslen(pszRegPath) || NULL == pszSearchKey || 0 == ::_tcslen(pszSearchKey))
{
return;
}
// 什么都不搜索
if (false == isSearchKey && false == isSearchValueName && false == isSearchValueData)
{
return;
}
const long MAX_KEY = 255; // 键最大长度
const long MAX_VALUENAME = 16383; // 值名最大长度
TCHAR* pszRegPathCopy = NULL; // pszRegPath 字符串拷贝
TCHAR* pszRegSubPath = NULL; // 子键路径字符串
HKEY hPredKey = NULL; // 系统预设主键句柄
HKEY hKey = NULL; // 操作键句柄
DWORD dwSubKeyCount = 0; // 当前子键数
DWORD dwValueCount = 0; // 当前键值数
DWORD cbSubKey = MAX_KEY; // 子键字符串长度
TCHAR pszSubKey[MAX_KEY] = _T(""); // 子键字符串
DWORD dwValueNameLength = MAX_VALUENAME; // 值名字符串长度
TCHAR pszValueName[MAX_VALUENAME] = _T(""); // 值名字符串
DWORD dwType = 0; // 键值数据类型
DWORD cbData = 0; // 键值数据大小(byte)
BYTE* lpData = NULL; // 键值数据
// pszRegPath 字符串做为常量传入,不允许修改,
// 所以需创建 Reg 字符串的拷贝,用于后续操作。
pszRegPathCopy = (TCHAR*)::malloc((::_tcslen(pszRegPath) + 1) * sizeof(TCHAR));
::_tcscpy(pszRegPathCopy, pszRegPath);
// 提取系统预设主键字符串
::_tcsstr(pszRegPathCopy, _T("\\"))[0] = _T('\0');
// 判断获取 hPredKey
if (0 == ::_tcsicmp(pszRegPathCopy, _T("HKEY_CLASSES_ROOT")) ||
0 == ::_tcsicmp(pszRegPathCopy, _T("HKCR")))
{
hPredKey = HKEY_CLASSES_ROOT;
}
else if (0 == ::_tcsicmp(pszRegPathCopy, _T("HKEY_LOCAL_MACHINE")) ||
0 == ::_tcsicmp(pszRegPathCopy, _T("HKLM")))
{
hPredKey = HKEY_LOCAL_MACHINE;
}
else if (0 == ::_tcsicmp(pszRegPathCopy, _T("HKEY_CURRENT_USER")) ||
0 == ::_tcsicmp(pszRegPathCopy, _T("HKCU")))
{
hPredKey = HKEY_CURRENT_USER;
}
else if (0 == ::_tcsicmp(pszRegPathCopy, _T("HKEY_USERS")) ||
0 == ::_tcsicmp(pszRegPathCopy, _T("HKU")))
{
hPredKey = HKEY_USERS;
}
else if (0 == ::_tcsicmp(pszRegPathCopy, _T("HKEY_PERFORMANCE_DATA")) ||
0 == ::_tcsicmp(pszRegPathCopy, _T("HKPD")))
{
hPredKey = HKEY_PERFORMANCE_DATA;
}
else if (0 == ::_tcsicmp(pszRegPathCopy, _T("HKEY_PERFORMANCE_TEXT")) ||
0 == ::_tcsicmp(pszRegPathCopy, _T("HKPT")))
{
hPredKey = HKEY_PERFORMANCE_TEXT;
}
else if (0 == ::_tcsicmp(pszRegPathCopy, _T("HKEY_PERFORMANCE_NLSTEXT")) ||
0 == ::_tcsicmp(pszRegPathCopy, _T("HKPN")))
{
hPredKey = HKEY_PERFORMANCE_NLSTEXT;
}
else if (0 == ::_tcsicmp(pszRegPathCopy, _T("HKEY_CURRENT_CONFIG")) ||
0 == ::_tcsicmp(pszRegPathCopy, _T("HKCC")))
{
hPredKey = HKEY_CURRENT_CONFIG;
}
else if (0 == ::_tcsicmp(pszRegPathCopy, _T("HKEY_DYN_DATA")) ||
0 == ::_tcsicmp(pszRegPathCopy, _T("HKDD")))
{
hPredKey = HKEY_DYN_DATA;
}
else
{
return;
}
if (NULL != pszRegPathCopy)
{
::free(pszRegPathCopy);
pszRegPathCopy = NULL;
}
// 创建 pszRegPath 字符串的新拷贝
pszRegPathCopy = (TCHAR*)::malloc((::_tcslen(pszRegPath) + 1) * sizeof(TCHAR));
::_tcscpy(pszRegPathCopy, pszRegPath);
// 提取子键路径字符串
pszRegSubPath = ::_tcsstr(pszRegPathCopy, _T("\\"));
if (NULL != pszRegSubPath)
{
pszRegSubPath++;
if (ERROR_SUCCESS != ::RegOpenKeyEx(hPredKey, pszRegSubPath, 0, KEY_READ, &hKey))
{
return;
}
}
else
{
hKey = hPredKey;
}
if (NULL != pszRegPathCopy)
{
::free(pszRegPathCopy);
pszRegPathCopy = NULL;
}
// 获取键信息(主要是子键数和键值数,用于下面遍历)
// 注:也可以不用主动获取数量,而由枚举函数(RegEnumXXX)返回 ERROR_NO_MORE_ITEMS 来判断枚举结束。
if (ERROR_SUCCESS != ::RegQueryInfoKey(hKey, NULL, NULL, NULL, &dwSubKeyCount, NULL, NULL, &dwValueCount, NULL, NULL, NULL, NULL))
{
if (NULL != hKey)
{
::RegCloseKey(hKey);
hKey = NULL;
}
return;
}
// 遍历子键
if (0 != dwSubKeyCount)
{
for (DWORD i = 0; i < dwSubKeyCount; i++)
{
cbSubKey = MAX_KEY;
if (ERROR_SUCCESS == ::RegEnumKeyEx(hKey, i, pszSubKey, &cbSubKey, NULL, NULL, NULL, NULL))
{
TCHAR pszNextPath[1024]; // 1024 为预估大小,不够则适当加大
_stprintf(pszNextPath, _T("%s\\%s"), pszRegPath, pszSubKey);
SearchInReg(fnOnSearchProc, pszNextPath, pszSearchKey, isFuzzy, isSearchKey, isSearchValueName, isSearchValueData); // 递归
// 回调处理搜索过程
fnOnSearchProc(false, pszNextPath, NULL, hKey);
// 比对子键
if (true == isSearchKey && // 判断是否要求比对子键
true == isFuzzy ? // 判断是否采用模糊方式
NULL != ::_tcsstr(pszSubKey, pszSearchKey) : // 采用模糊方式比对
0 == ::_tcsicmp(pszSearchKey, pszSubKey)) // 采用非模糊方式比对
{
// 回调处理搜索结果
TCHAR* pszResultText = NULL; // 结果字段(用于显示)
TCHAR* pszMatched = NULL; // 被匹配部分的字段
HKEY hResultKey = NULL; // 当前键的句柄,用于在回调中对该键操作
pszResultText = (TCHAR*)::malloc((::_tcslen(pszNextPath) + 1) * sizeof(TCHAR));
::_tcscpy(pszResultText, pszNextPath);
pszMatched = (TCHAR*)::malloc((::_tcslen(pszSubKey) + 1) * sizeof(TCHAR));
::_tcscpy(pszMatched, pszSubKey);
::RegOpenKeyEx(hKey, pszSubKey, 0, KEY_ALL_ACCESS, &hResultKey);
fnOnSearchProc(true, pszResultText, pszMatched, hKey);
// 清理
if (NULL != pszResultText)
{
::free(pszResultText);
pszResultText = NULL;
}
if (NULL != pszMatched)
{
::free(pszMatched);
pszMatched = NULL;
}
if (NULL != hResultKey)
{
::RegCloseKey(hResultKey);
hResultKey = NULL;
}
}
}
}
}
// 遍历键值
if (0 != dwValueCount)
{
for (DWORD i = 0; i < dwValueCount; i++)
{
if (ERROR_SUCCESS == ::RegEnumValue(hKey, i, pszValueName, &dwValueNameLength, NULL, &dwType, NULL, &cbData))
{
// 比对值名
if (true == isSearchValueName && // 判断是否要求比对值名
true == isFuzzy ? // 判断是否采用模糊方式
NULL != ::_tcsstr(pszValueName, pszSearchKey) : // 采用模糊方式比对
0 == ::_tcsicmp(pszSearchKey, pszValueName)) // 采用非模糊方式比对
{
// 回调处理搜索结果
TCHAR* pszResultText = NULL; // 结果字段(用于显示)
TCHAR* pszMatched = NULL; // 匹配部分字段
HKEY hResultKey = NULL; // 当前键的句柄,用于在回调中对该键操作
pszResultText = (TCHAR*)::malloc((::_tcslen(pszRegPath) + ::_tcslen(pszValueName) + 4) * sizeof(TCHAR));
_stprintf(pszResultText, _T("%s \"%s\""), pszRegPath, pszValueName);
pszMatched = (TCHAR*)::malloc((::_tcslen(pszValueName) + 1) * sizeof(TCHAR));
::_tcscpy(pszMatched, pszValueName);
::RegOpenKeyEx(hKey, pszSubKey, 0, KEY_ALL_ACCESS, &hResultKey);
fnOnSearchProc(true, pszResultText, pszMatched, hKey);
// 清理
if (NULL != pszResultText)
{
::free(pszResultText);
pszResultText = NULL;
}
if (NULL != pszMatched)
{
::free(pszMatched);
pszMatched = NULL;
}
if (NULL != hResultKey)
{
::RegCloseKey(hResultKey);
hResultKey = NULL;
}
}
// 判断若该值为字符串格式且不为空,则对值进行比对
if ((REG_SZ == dwType || REG_MULTI_SZ == dwType || REG_EXPAND_SZ == dwType) && 0 != cbData)
{
lpData = (BYTE*)::malloc(cbData);
if (ERROR_SUCCESS == ::RegQueryValueEx(hKey, pszValueName, NULL, NULL, lpData, &cbData))
{
// 将值转换为字符串类型
TCHAR* pszValueData = (TCHAR*)::malloc(cbData);
::_tcscpy(pszValueData, (TCHAR*)lpData);
// 对比值
if (true == isSearchValueData && // 判断是否要求比对值
true == isFuzzy ? // 判断是否采用模糊方式
NULL != ::_tcsstr(pszValueData, pszSearchKey) : // 采用模糊方式比对
0 == ::_tcsicmp(pszSearchKey, pszValueData)) // 采用非模糊方式比对
{
// 回调处理搜索结果
TCHAR* pszResultText = NULL; // 结果字段(用于显示)
TCHAR* pszMatched = NULL; // 匹配部分字段
HKEY hResultKey = NULL; // 当前键的句柄,用于在回调中对该键操作
pszResultText = (TCHAR*)::malloc((::_tcslen(pszRegPath) + ::_tcslen(pszValueName) + ::_tcslen(pszValueData) + 8) * sizeof(TCHAR));
_stprintf(pszResultText, _T("%s \"%s\"=\"%s\""), pszRegPath, pszValueName, pszValueData);
pszMatched = (TCHAR*)::malloc((::_tcslen(pszValueData) + 1) * sizeof(TCHAR));
::_tcscpy(pszMatched, pszValueData);
::RegOpenKeyEx(hKey, pszSubKey, 0, KEY_ALL_ACCESS, &hResultKey);
fnOnSearchProc(true, pszResultText, pszMatched, hKey);
// 清理
if (NULL != pszResultText)
{
::free(pszResultText);
pszResultText = NULL;
}
if (NULL != pszMatched)
{
::free(pszMatched);
pszMatched = NULL;
}
if (NULL != hResultKey)
{
::RegCloseKey(hResultKey);
hResultKey = NULL;
}
}
// 清理
if (NULL != pszValueData)
{
::free(pszValueData);
pszValueData = NULL;
}
}
// 清理
if (NULL != lpData)
{
::free(lpData);
lpData = NULL;
}
}
}
}
}
// 清理
if (NULL != hKey)
{
::RegCloseKey(hKey);
hKey = NULL;
}
}
/* SearchInReg 使用演示 -------------------------------------------------------------------------------------
DWORD dwCount = 0;
void CALLBACK OnSearchProc(bool isFound, const TCHAR* pszResultText, const TCHAR* pszMatched, const HKEY& hKey)
{
if (true == isFound)
{
dwCount++;
_tprintf(_T("---------------------------------------------\n"));
_tprintf(_T("找到第 %d 个\n"), dwCount);
_tprintf(_T("%s\n"), pszResultText);
_tprintf(_T("%s\n"), pszMatched);
_tprintf(_T("---------------------------------------------\n"));
}
}
void _tmain(void)
{
SearchInReg(OnSearchProc, _T("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows"), _T("System"));
}
// SearchInReg 使用演示 -----------------------------------------------------------------------------------*/发表于 @ 2007年09月07日 01:24:00|评论(loading...)|收藏