首先描述下寫這個代碼的思路,我的本意是想要從Windows 2000註冊表裏獲取PC已安裝的補丁信息,已知路徑HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Updates,但是它下面還有很多路徑,由於我只有這一臺虛擬機,所以不敢確定其他2000的pc也是這種固定路徑,所以打算遞歸遍歷HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Updates下面所有的項,然後過濾掉不含KB的項。一開始想一氣呵成,把所有流程寫完,但是寫完發現把自己繞坑裏了。後面濾清思路,先寫個遞歸遍歷註冊表的,然後再在裏面添加TODO。果然很快就搞定了。
遞歸遍歷註冊表的思路:
void search()
{
//打開一個項
//獲取他下面有多少個子項
//循環遍歷每一個子項 獲取子項名字
search
}
遞歸遍歷註冊表的代碼:
void SearchKey(HKEY hKey, LPCTSTR lpSubKey)
{
HKEY hSubKey = NULL;
char subKeyName[MAX_PATH+1] = {0};
if (ERROR_SUCCESS == RegOpenKeyEx(hKey, lpSubKey, 0, KEY_ALL_ACCESS, &hSubKey))
{
//獲取lpSubKey下面有多少個子項
DWORD dwSubKey = GetRegKeyCount( hSubKey, 0, NULL, 0 );
for (int i=0; i<dwSubKey; i++)
{
ERROR_SUCCESS == RegEnumKey(hSubKey, i, subKeyName, MAX_PATH);
//打印項的名字
printf("%s\n", subKeyName);
SearchKey(hSubKey, subKeyName);
}
//關閉
if (hSubKey)
{
RegCloseKey(hSubKey);
}
}
}
獲取一個項下面的子項數量:
DWORD GetRegKeyCount(HKEY hKey, DWORD dwIndex, TCHAR *achKey, DWORD dwKeyLen)
{
LONG lRet = ERROR_SUCCESS;
DWORD cSubKeys = 0;
DWORD cMaxKeyLens = 0;
lRet = RegQueryInfoKey(hKey, NULL, NULL, NULL, &cSubKeys, &cMaxKeyLens, NULL, NULL, NULL, NULL, NULL, NULL);
if (lRet != ERROR_SUCCESS)
{
return 0;
}
if (cSubKeys != 0 && achKey != NULL)
{
lRet = RegEnumKeyEx(
hKey,
dwIndex,
achKey,
&dwKeyLen,
NULL,
NULL,
NULL,
NULL
);
if (lRet != ERROR_SUCCESS)
{
return 0;
}
}
return cSubKeys;
}