首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

VC 讀取註冊表枚舉已安裝程式並獲取詳細屬性完整實作

     編輯:關於VC++

Windows 系統安裝程式資訊集中存放於註冊表 HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall,XP 至 Win11 皆適用。本文提供兩層級完整讀取實作:首層枚舉所有安裝項目,次層深入讀取各項目詳細屬性。

註冊表結構認知

  • 每個子鍵 = 一個安裝程式項目 (GUID 或名稱)
  • 子鍵下包含值:DisplayName、Publisher、InstallDate、EstimatedSize (KB)、DisplayVersion、UninstallString 等
  • 32 位應用在 64 位系統可能位於 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"));

64 位系統相容性關鍵

為同時枚舉 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 控制視圖。

常見屬性值說明

值名稱類型說明
DisplayNameREG_SZ顯示名稱 (控制台顯示)
PublisherREG_SZ發行者
InstallDateREG_SZYYYYMMDD 格式日期
EstimatedSizeREG_DWORD預估大小 (KB)
DisplayVersionREG_SZ版本字串
UninstallStringREG_SZ/EXPAND_SZ解除安裝命令列
QuietUninstallStringREG_SZ/EXPAND_SZ靜默解除安裝命令
InstallLocationREG_SZ安裝目錄

權限與效能提示

  • 需管理員權限讀取 HKLM,或改讀 HKCU (用戶級安裝)
  • 大量項目時 RegEnumKeyEx 迴圈耗時,建議背景執行緒執行並分批更新 UI
  • 字串緩衝區固定 256,極長值可能截斷,生產碼建議先查詢大小再配置
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved