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

VC++ 登錄操作完整指南:查詢與修改系統註冊表鍵值實戰

     編輯:關於VC++

前言:註冊表架構與 VC++ 存取方式

Windows 註冊表採樹狀結構,包含六大根鍵 (HKEY_LOCAL_MACHINE 等),每鍵含多層子鍵與值。VC++ 透過 Win32 API (RegOpenKeyEx, RegQueryValueEx, RegSetValueEx 等) 實作存取。本文以「查詢/修改註冊使用者名稱與公司名稱」為例,示範完整流程與錯誤處理。

目標鍵值位置

根鍵: HKEY_LOCAL_MACHINE
路徑: Software\\Microsoft\\Windows\\CurrentVersion
值名: RegisteredOwner (使用者名稱), RegisteredOrganization (公司名稱)

一、查詢使用者資訊

HKEY hKey;
LPCTSTR dataPath = _T("Software\\Microsoft\\Windows\\CurrentVersion\\");
LONG ret = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, dataPath, 0, KEY_READ, &hKey);
if (ret != ERROR_SUCCESS) { MessageBox(_T("無法開啟鍵值!")); return; }

BYTE* ownerData = new BYTE[80];
DWORD type = REG_SZ, size = 80;
ret = ::RegQueryValueEx(hKey, _T("RegisteredOwner"), NULL, &type, ownerData, &size);
if (ret != ERROR_SUCCESS) { MessageBox(_T("查詢失敗!")); delete[] ownerData; ::RegCloseKey(hKey); return; }

BYTE* companyData = new BYTE[80];
size = 80;
ret = ::RegQueryValueEx(hKey, _T("RegisteredOrganization"), NULL, &type, companyData, &size);
if (ret != ERROR_SUCCESS) { MessageBox(_T("查詢失敗!")); delete[] ownerData; delete[] companyData; ::RegCloseKey(hKey); return; }

CString strOwner = CString((char*)ownerData);
CString strCompany = CString((char*)companyData);
delete[] ownerData; delete[] companyData;
::RegCloseKey(hKey);
// 此處顯示 strOwner, strCompany

二、修改使用者資訊

關鍵:需以 KEY_WRITE 開啟鍵值,並將 CString 轉 LPBYTE。

輔助函式:CString → LPBYTE

LPBYTE CStringToLPBYTE(CString str) {
    LPBYTE lpb = new BYTE[str.GetLength() + 1];
    for (int i = 0; i < str.GetLength(); i++)
        lpb[i] = (BYTE)str[i];
    lpb[str.GetLength()] = 0;
    return lpb;
}

修改主程式碼

CString strOwner, strCompany;
// ... 透過對話方塊取得新值 ...

HKEY hKey;
LPCTSTR dataPath = _T("Software\\Microsoft\\Windows\\CurrentVersion");
LONG ret = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, dataPath, 0, KEY_WRITE, &hKey);
if (ret != ERROR_SUCCESS) { MessageBox(_T("無法開啟鍵值!")); return; }

LPBYTE ownerSet = CStringToLPBYTE(strOwner);
DWORD type = REG_SZ, size = strOwner.GetLength() + 1;
ret = ::RegSetValueEx(hKey, _T("RegisteredOwner"), NULL, type, ownerSet, size);
if (ret != ERROR_SUCCESS) { MessageBox(_T("修改使用者名稱失敗!")); delete[] ownerSet; ::RegCloseKey(hKey); return; }

LPBYTE companySet = CStringToLPBYTE(strCompany);
size = strCompany.GetLength() + 1;
ret = ::RegSetValueEx(hKey, _T("RegisteredOrganization"), NULL, type, companySet, size);
if (ret != ERROR_SUCCESS) { MessageBox(_T("修改公司名稱失敗!")); }

delete[] ownerSet; delete[] companySet;
::RegCloseKey(hKey);
// 修改完成,可開啟 regedit 驗證

常見陷阱與最佳實踐

  • 權限問題:Vista 以降需管理員權限寫入 HKLM,建議加入 UAC 清單
  • 字串編碼:REG_SZ 為 ANSI,Unicode 專案需用 REG_EXPAND_SZ 或轉碼
  • 錯誤處理:每步 API 呼叫必檢查回傳值,善用 GetLastError()
  • 資源釋放:RegCloseKey、delete[] 必配對,避免洩漏
  • 備份機制:修改前先匯出 .reg 檔,提供還原途徑

擴充應用:通用註冊表操作類別封裝建議

class CRegistryHelper {
public:
    static BOOL ReadString(HKEY hRoot, LPCTSTR subKey, LPCTSTR value, CString& out);
    static BOOL WriteString(HKEY hRoot, LPCTSTR subKey, LPCTSTR value, LPCTSTR data);
    static BOOL DeleteKey(HKEY hRoot, LPCTSTR subKey);
    static BOOL DeleteValue(HKEY hRoot, LPCTSTR subKey, LPCTSTR value);
    // 內部統一錯誤處理、記憶體管理、Unicode 轉換
};
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved