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。
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 驗證
HKLM,建議加入 UAC 清單REG_SZ 為 ANSI,Unicode 專案需用 REG_EXPAND_SZ 或轉碼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 轉換
};