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

VC++ 登錄表操作完整指南:從開啟、建立到讀寫鍵值

     編輯:VC 教學

前言

在 Windows 程式開發中,登錄表是儲存應用程式設定、使用者偏好及系統配置的核心資料庫。雖然 MFC 提供了 CRegKey 類別封裝常用操作,但直接呼叫 Win32 API(RegOpenKeyEx、RegCreateKeyEx、RegSetValueEx、RegQueryValueEx)能更靈活地控制權限、資料型別與錯誤處理。本文以實戰範例示範如何在 HKEY_LOCAL_MACHINE\SOFTWARE 下建立或開啟自訂鍵值,並完成 DWORD 與字串型別的讀寫。

核心 API 速查

函式用途關鍵參數
RegOpenKeyEx開啟現有鍵根鍵、子鍵路徑、存取權限(如 KEY_ALL_ACCESS)、輸出句柄
RegCreateKeyEx建立或開啟鍵(不存在則建立)類別名稱、選項(REG_OPTION_NON_VOLATILE 表永久)、安全屬性、處置狀態
RegSetValueEx寫入鍵值值名稱、型別(REG_DWORD/REG_SZ)、資料指標、資料長度
RegQueryValueEx讀取鍵值輸出型別、資料緩衝區、資料長度指標
RegCloseKey釋放鍵句柄必須在完成操作後呼叫,避免資源洩漏

完整範例程式碼

HKEY hKey = HKEY_LOCAL_MACHINE;
LPCTSTR lpszSubKey = _T("SOFTWARE\\MyProgram");  // 注意路徑分隔符
HKEY hKeyResult = NULL;
LONG ret;
DWORD dwType, dwSize;

// 1. 嘗試開啟鍵
ret = RegOpenKeyEx(hKey, lpszSubKey, 0, KEY_ALL_ACCESS, &hKeyResult);

if (ret != ERROR_SUCCESS) {
    // 2. 開啟失敗 → 建立鍵
    ret = RegCreateKeyEx(hKey, lpszSubKey, 0, NULL,
                         REG_OPTION_NON_VOLATILE,
                         KEY_READ | KEY_WRITE,
                         NULL, &hKeyResult, NULL);

    if (ret != ERROR_SUCCESS) {
        MessageBox(_T("建立鍵失敗!"));
        return;
    }

    // 3. 寫入預設值:Number (DWORD) 與 Date (字串)
    LPCTSTR lpszValueName = _T("Number");
    DWORD dwNumber = 10;
    RegSetValueEx(hKeyResult, lpszValueName, 0, REG_DWORD,
                  (CONST BYTE*)&dwNumber, sizeof(DWORD));

    lpszValueName = _T("Date");
    LPCTSTR lpszDate = _T("2006/4/29");
    RegSetValueEx(hKeyResult, lpszValueName, 0, REG_SZ,
                  (CONST BYTE*)lpszDate, (lstrlen(lpszDate)+1)*sizeof(TCHAR));

    RegCloseKey(hKeyResult);
}
else {
    // 4. 開啟成功 → 讀取值
    DWORD dwRes = 0;
    dwType = REG_DWORD;
    dwSize = sizeof(DWORD);
    ret = RegQueryValueEx(hKeyResult, _T("Number"), 0, &dwType,
                          (BYTE*)&dwRes, &dwSize);
    if (ret != ERROR_SUCCESS) {
        MessageBox(_T("讀取 Number 失敗!"));
    }
    // dwRes 即為讀回的數值

    // 讀取字串值
    TCHAR szDate[MAX_PATH] = {0};
    dwType = REG_SZ;
    dwSize = sizeof(szDate);
    ret = RegQueryValueEx(hKeyResult, _T("Date"), 0, &dwType,
                          (BYTE*)szDate, &dwSize);
    if (ret != ERROR_SUCCESS) {
        MessageBox(_T("讀取 Date 失敗!"));
    }
    // szDate 即為讀回的字串

    RegCloseKey(hKeyResult);
}

關鍵細節與最佳實務

  • 路徑分隔符:子鍵路徑必須使用雙反斜線 \\ 或單一 \(在字串常值中寫成 \\\\),否則會被視為跳脫字元。
  • 權限最小化:僅需讀取時請用 KEY_READ,需寫入才加 KEY_WRITE,避免因權限不足導致存取被拒。
  • 字串長度計算:呼叫 RegSetValueEx 寫 REG_SZ 時,長度應包含結束的 null 字元,建議用 (lstrlen(str)+1)*sizeof(TCHAR)。
  • 緩衝區大小:讀取前先以 RegQueryValueEx 取得所需緩衝區大小(傳 NULL 給資料指標),再配置記憶體,防止截斷。
  • 錯誤代碼:所有 API 回傳 LONG,成功為 ERROR_SUCCESS(0),失敗可用 FormatMessage 取得可讀訊息。

延伸應用

實務上常將上述邏輯封裝為 CRegistry 工具類別,提供 WriteDWORD、ReadString、DeleteKey、EnumSubKeys 等方法,並搭配 RAII 自動管理 HKEY 生命週期,進一步簡化呼叫端程式碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved