Windows 系統安裝程式資訊集中存放於註冊表 HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall,XP 至 Win11 皆適用。本文提供兩層級完整讀取實作:首層枚舉所有安裝項目,次層深入讀取各項目詳細屬性。
DisplayName、Publisher、InstallDate、EstimatedSize (KB)、DisplayVersion、UninstallString 等Wow6432Node 子路徑BOOL CMyListCtrlTestDlg::AllRegKey(HKEY hKey, LPCTSTR szDesKeyItem) {
HKEY hSubKey;
DWORD dwIndex = 0;
LONG lResult = RegOpenKeyEx(hKey, szDesKeyItem, 0, KEY_READ, &hSubKey);
if (ERROR_SUCCESS != lResult) return FALSE;
TCHAR szKeyName[256];
DWORD cbName = 256 * sizeof(TCHAR);
int i = 1;
lResult = RegEnumKeyEx(hSubKey, dwIndex, szKeyName, &cbName, 0, NULL, NULL, NULL);
while (lResult == ERROR_SUCCESS && lResult != ERROR_MORE_DATA) {
OutputDebugString(szKeyName);
CString str; str.Format(_T("%d"), i);
i = m_MyList.InsertItem(i, str);
m_MyList.SetItemText(i, 1, szKeyName);
dwIndex++;
cbName = 256 * sizeof(TCHAR);
lResult = RegEnumKeyEx(hSubKey, dwIndex, szKeyName, &cbName, 0, NULL, NULL, NULL);
i++;
}
RegCloseKey(hSubKey);
return TRUE;
}
BOOL CSoftList::AllRegKey(HKEY hKey, LPCTSTR szDesKeyItem) {
HKEY hSubKey;
DWORD dwIndex = 0;
LONG lResult = RegOpenKeyEx(hKey, szDesKeyItem, 0, KEY_READ, &hSubKey);
if (ERROR_SUCCESS != lResult) return FALSE;
TCHAR s_name[256], s_DisplayName[256], s_Publisher[256], s_InstallDate[12], s_DisplayVersion[256];
DWORD s_EstimatedSize, cbName = 256 * sizeof(TCHAR), cbName2 = sizeof(DWORD);
DWORD typeSZ = REG_SZ, typeDWORD = REG_DWORD;
int id = 1;
lResult = RegEnumKeyEx(hSubKey, dwIndex, s_name, &cbName, 0, NULL, NULL, NULL);
while (lResult == ERROR_SUCCESS && lResult != ERROR_MORE_DATA) {
OutputDebugString(s_name);
CString str; str.Format(_T("%d"), id);
id = m_SoftList.InsertItem(id, str);
m_SoftList.SetItemText(id, 1, s_name); // 預設顯示鍵名
HKEY hItem;
if (RegOpenKeyEx(hSubKey, s_name, 0, KEY_READ, &hItem) == ERROR_SUCCESS) {
// 讀取各屬性值,存在則覆蓋顯示
if (RegQueryValueEx(hItem, _T("DisplayName"), 0, &typeSZ, (LPBYTE)s_DisplayName, &cbName) == ERROR_SUCCESS)
m_SoftList.SetItemText(id, 1, s_DisplayName);
if (RegQueryValueEx(hItem, _T("Publisher"), 0, &typeSZ, (LPBYTE)s_Publisher, &cbName) == ERROR_SUCCESS)
m_SoftList.SetItemText(id, 2, s_Publisher);
if (RegQueryValueEx(hItem, _T("InstallDate"), 0, &typeSZ, (LPBYTE)s_InstallDate, &cbName) == ERROR_SUCCESS) {
if (s_InstallDate[0]) m_SoftList.SetItemText(id, 3, s_InstallDate); // 非空才顯示
}
if (RegQueryValueEx(hItem, _T("EstimatedSize"), 0, &typeDWORD, (LPBYTE)&s_EstimatedSize, &cbName2) == ERROR_SUCCESS) {
float fSizeMB = s_EstimatedSize / 1024.0f;
CString szSize; szSize.Format(_T("%.2f MB"), fSizeMB);
m_SoftList.SetItemText(id, 4, szSize);
}
if (RegQueryValueEx(hItem, _T("DisplayVersion"), 0, &typeSZ, (LPBYTE)s_DisplayVersion, &cbName) == ERROR_SUCCESS)
m_SoftList.SetItemText(id, 5, s_DisplayVersion);
RegCloseKey(hItem);
}
dwIndex++;
cbName = 256 * sizeof(TCHAR);
lResult = RegEnumKeyEx(hSubKey, dwIndex, s_name, &cbName, 0, NULL, NULL, NULL);
id++;
}
RegCloseKey(hSubKey);
return TRUE;
}
AllRegKey(HKEY_LOCAL_MACHINE,
_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"));
為同時枚舉 32/64 位應用,需分別讀取:
// 64 位視圖 (預設)
AllRegKey(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"));
// 32 位視圖 (Wow6432Node)
AllRegKey(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"));
或使用 KEY_WOW64_64KEY / KEY_WOW64_32KEY 標誌配合 RegOpenKeyEx 控制視圖。
| 值名稱 | 類型 | 說明 |
|---|---|---|
| DisplayName | REG_SZ | 顯示名稱 (控制台顯示) |
| Publisher | REG_SZ | 發行者 |
| InstallDate | REG_SZ | YYYYMMDD 格式日期 |
| EstimatedSize | REG_DWORD | 預估大小 (KB) |
| DisplayVersion | REG_SZ | 版本字串 |
| UninstallString | REG_SZ/EXPAND_SZ | 解除安裝命令列 |
| QuietUninstallString | REG_SZ/EXPAND_SZ | 靜默解除安裝命令 |
| InstallLocation | REG_SZ | 安裝目錄 |
HKLM,或改讀 HKCU (用戶級安裝)RegEnumKeyEx 迴圈耗時,建議背景執行緒執行並分批更新 UI