C++Builder 封裝 Win32 註冊表 API 為 TRegistry 類,提供物化的鍵值讀寫、鍵創建/刪除、數據類型自動轉換。本文詳解 TRegistry 核心屬性方法、RootKey 動態切換、鍵路徑導航、數據類型對應、異常安全模式,並給出「寫入啟動項」完整示例。
TRegistry 核心屬性
| 屬性 | 類型 | 說明 |
RootKey | HKEY | 當前根鍵,默認 HKEY_CURRENT_USER。可動態切換:HKEY_LOCAL_MACHINE、HKEY_CLASSES_ROOT、HKEY_USERS、HKEY_CURRENT_CONFIG、HKEY_DYN_DATA |
CurrentPath | String | 只讀,當前打開鍵的完整路徑 (相對 RootKey) |
LazyWrite | bool | true (默認) 延遲寫入刷新,false 即時同步 |
核心方法速查
| 方法 | 作用 | 返回/備註 |
OpenKey(const String& Key, bool CanCreate) | 打開/創建子鍵 | true 成功,CanCreate=true 不存在時自動創建 |
CloseKey() | 關閉當前鍵 | 必須成對調用 |
DeleteKey(const String& Key) | 刪除子鍵 (遞歸) | 慎用 |
KeyExists(const String& Key) | 檢查子鍵是否存在 | bool |
ValueExists(const String& Name) | 檢查值是否存在 | bool |
GetKeyNames(TStrings* List) | 枚舉子鍵名稱 | 填充 List |
GetValueNames(TStrings* List) | 枚舉值名稱 | 填充 List |
GetDataSize(const String& Name) | 獲取值數據字節數 | int |
數據類型讀寫方法對照
| 註冊表類型 | 讀取方法 | 寫入方法 | C++ 類型 |
| REG_SZ / REG_EXPAND_SZ | ReadString() | WriteString(const String&) | String |
| REG_DWORD / REG_DWORD_LITTLE_ENDIAN | ReadInteger() | WriteInteger(int) | int (32位) |
| REG_QWORD (Win7+) | ReadInt64() | WriteInt64(__int64) | __int64 |
| REG_BINARY | ReadBinaryData(void* Buf, int Size) | WriteBinaryData(const void* Buf, int Size) | 任意二進制 |
| REG_MULTI_SZ | ReadStringList(TStrings*) | WriteStringList(TStrings*) | TStringList* |
完整示例:向 HKLM\Run 寫入開機啟動項
void WriteToRunRegistry(const String& valueName, const String& exePath) {
TRegistry* reg = new TRegistry;
try {
reg->RootKey = HKEY_LOCAL_MACHINE; // 切換根鍵
if (!reg->OpenKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run", true)) {
throw Exception("無法打開/創建 Run 鍵");
}
reg->WriteString(valueName, exePath); // 如 "MyApp", "C:\\MyApp.exe"
}
__finally {
reg->CloseKey();
delete reg;
}
}
讀取示例:枚舉所有啟動項
void EnumRunKeys(TStringList* output) {
TRegistry* reg = new TRegistry;
try {
reg->RootKey = HKEY_LOCAL_MACHINE;
if (reg->OpenKeyReadOnly("Software\\Microsoft\\Windows\\CurrentVersion\\Run")) {
reg->GetValueNames(output); // 獲取所有值名稱
// 可進一步 ReadString 獲取路徑
}
}
__finally {
reg->CloseKey();
delete reg;
}
}
TRegIniFile 替代方案 (INI 風格 API)
- 繼承自
TRegistry,但暴露 ReadString(Section, Ident, Default) 等 INI 風格方法;
- 內部自動將 Section 轉為子鍵,Ident 轉為值名;
- 適合從 INI 遷移到註冊表的舊項目,**新代碼建議直接用 TRegistry**。
避坑指南
- ❌ **忘記 `CloseKey()`** → 句柄洩漏,導致後續操作失敗;
- ❌ **寫入 HKLM 需管理員權限** — Vista+ UAC 下普通進程寫入失敗 (返回 false/拋異常),需清單提升或服務寫入;
- ❌ **路徑分隔符** — 統一用雙反斜杠 `\\` 或單反斜杠 `\` (BCB String 字面量),不要混用 `/`;
- ❌ **大小寫敏感** — 註冊表鍵值名**不區分大小寫**,但 `TRegistry` 方法參數建議與實際大小寫一致;
- ✅ **異常安全** — 必須用 `try__finally` 包裹 `delete reg`,防內存洩漏;
- ✅ **大數據讀取** — 先 `GetDataSize` 分配緩衝區,再 `ReadBinaryData`,避免棧溢出;
- ✅ **64 位系統重定向** — 32 位進程訪問 `HKLM\Software` 會被重定向到 `HKLM\Software\WOW6432Node`,若需操作真 64 位視圖,需用 `KEY_WOW64_64KEY` 標志 (BCB 需直接調用 Win32 API)。
熟練掌握 TRegistry,能將註冊表操作從繁瑣的 Win32 API 解脫,變為類型安全、異常安全、可讀性強的 C++ 代碼。