首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

VC++ 註冊表創建新鍵值失敗的解決方案

     編輯:程式設計綜合問答

問題描述

在 VC++ 中嘗試向註冊表 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall 下創建新項 RuanJianBox,但遇到以下問題:

  • 使用 RegCreateKey 返回值正確,但註冊表編輯器中不顯示新項。
  • 使用 RegCreateKeyEx 返回錯誤碼 1(ERROR_INVALID_FUNCTION)。
  • 此外,如何在新建項下進一步創建鍵值?

代碼分析

HKEY sub;
CString skey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\RuanJianBox";
if (::RegCreateKey(HKEY_LOCAL_MACHINE, skey, &sub)) {
    MessageBox("創建成功");
}
DWORD dwDisposition = REG_CREATED_NEW_KEY;
int aaa = ERROR_SUCCESS == ::RegCreateKeyEx(
    HKEY_LOCAL_MACHINE, skey, 0, NULL,
    REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
    NULL, &sub, &dwDisposition
);
if (aaa != ERROR_SUCCESS) {
    CString strError;
    strError.Format("%d", aaa);
    MessageBox(strError);
}
::RegCloseKey(sub);

核心問題與解決

1. 權限不足(最常見原因)

寫入 HKEY_LOCAL_MACHINE 需要管理員權限。請確保程序以**管理員身份運行**,或在清單文件中聲明 requireAdministrator。

2. 參數傳遞錯誤

RegCreateKeyEx 的第 4 參數 lpClass 應傳遞 NULL 或類名字符串,而非 NULL 字面量;第 6 參數 samDesired 建議使用 KEY_WRITE | KEY_READ 而非 KEY_ALL_ACCESS,以減少權限需求。

3. 句柄未正確關閉導致數據未刷新

雖然代碼末尾調用了 RegCloseKey,但若中間發生錯誤跳過關閉,數據可能停留在緩存中。**務必在所有退出路徑中關閉句柄**,建議使用 RAII 封裝。

4. 64 位系統重定向

在 64 位 Windows 上,32 位程序訪問 HKEY_LOCAL_MACHINE\SOFTWARE 會被重定向到 Wow6432Node。若需操作 64 位視圖,需在 samDesired 中加入 KEY_WOW64_64KEY 標誌。

修正後的代碼示例

HKEY hKey = NULL;
LSTATUS status = RegCreateKeyEx(
    HKEY_LOCAL_MACHINE,
    L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\RuanJianBox",
    0, NULL,
    REG_OPTION_NON_VOLATILE,
    KEY_WRITE | KEY_READ | KEY_WOW64_64KEY, // 明確指定 64 位視圖
    NULL, &hKey, NULL
);

if (status == ERROR_SUCCESS) {
    // 創建鍵值示例
    const wchar_t* valueName = L"DisplayName";
    const wchar_t* valueData = L"My Software";
    RegSetValueEx(hKey, valueName, 0, REG_SZ,
        (const BYTE*)valueData, (wcslen(valueData) + 1) * sizeof(wchar_t));
    RegCloseKey(hKey);
    MessageBox(L"創建並寫入成功");
} else {
    CString msg;
    msg.Format(L"失敗,錯誤碼: %d", status);
    MessageBox(msg);
}

在新項下創建鍵值的步驟

  1. 成功打開/創建父項後,保留返回的 HKEY 句柄。
  2. 調用 RegSetValueEx,指定數據類型(REG_SZ, REG_DWORD 等)、名稱、數據指針及長度。
  3. 操作完成後調用 RegCloseKey 釋放句柄。

調試建議

  • 使用 GetLastError() 獲取詳細錯誤信息,而非僅依賴返回值。
  • 用註冊表編輯器確認項是否真實創建(注意 32/64 位視圖差異)。
  • 若仍失敗,嘗試寫入 HKEY_CURRENT_USER 驗證代碼邏輯,排除權限問題。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved