2009-08-27 231 views
7

我正在尋找一種乾淨的方式來檢查註冊表項是否存在。我曾假設如果我試圖打開一個不存在的密鑰,RegOpenKey會失敗,但它不會。檢查是否存在註冊表項

我可以使用字符串處理來查找並打開我正在查找的父鍵,然後枚舉該鍵的子鍵以查明我感興趣的鍵是否存在,但這兩者都感覺到就像性能豬一樣,並且像一種奇怪的方式來實現這樣一個簡單的功能。

我想你可以使用RegQueryInfoKey爲此,但MSDN並沒有提供太多的細節,以防萬一它是可能的。

更新:我需要直接win32 API的解決方案,而不是託管代碼,.NET或任何其他庫。

MSDN中的文檔似乎表明,你應該能夠打開讀取權限的關鍵,並得到一個錯誤,如果它不存在,就像這樣:

lResult = RegOpenKeyEx (hKeyRoot, lpSubKey, 0, KEY_READ, &hKey); 

if (lResult != ERROR_SUCCESS) 
{ 
    if (lResult == ERROR_FILE_NOT_FOUND) { 

不過,我得到ERROR_SUCCESS時我試試這個。

更新2:我確切的代碼是這樣的:

HKEY subKey = nullptr; 
LONG result = RegOpenKeyEx(key, subPath.c_str(), 0, KEY_READ, &subKey); 
if (result != ERROR_SUCCESS) { 

...但結果出來爲ERROR_SUCCESS,即使我已經把不存在的關鍵。

更新3:看起來你們是對的。這在一個特定的測試例子上(神祕地)失敗了。如果我在任何其他鍵上嘗試它,它會返回正確的結果。使用註冊表編輯器對其進行雙重檢查仍然不會顯示密鑰。不知道該怎麼做。

+4

你正在檢查的密鑰的路徑是什麼?是否有可能遇到重定向的魔法路徑之一(如Wow6432Node)?我有一個模糊的回憶,以前看到這個問題。我想你可以打開一個不存在的密鑰。實際嘗試設置或查詢該密鑰中的值時,您會失敗。 – 2009-08-27 21:37:01

+1

它也可以在[註冊表VirtualStore](http://msdn.microsoft.com/en-us/library/windows/desktop/aa965884%28v=vs.85%29.aspx)。 – ghord 2013-05-31 11:48:17

回答

7

首先,不要擔心像這樣的東西的表現。除非你每秒查詢它100次,否則它會更快。不成熟的優化會導致各種頭痛。

如果RegOpenKeyEx找到密鑰,它將返回ERROR_SUCCESS。只要檢查這個常數,你就很好。

+1

好吧,這不是一個過早優化的例子,因爲不想爲代碼增加這種複雜性。 – slicedlime 2009-08-27 20:58:33

4

RegOpenKey如果密鑰不存在,會返回錯誤。你怎麼使用它?預期回報值爲ERROR_FILE_NOT_FOUND

從代碼:

HKEY subKey = nullptr; 
LONG result = RegOpenKeyEx(key, subPath.c_str(), 0, KEY_READ, &subKey); 
if (result != ERROR_SUCCESS) { 

我會看的keysubPath的價值,並確保他們是你所期望的,那關鍵的實際上不存在。之後subKey的價值是多少?這顯然是開放的東西 - 嘗試枚舉它,看看它下面的鍵和值是什麼。

如果密鑰不存在,那麼RegOpenKey不會返回錯誤 - 我不會試圖假設在註冊表中常用的東西中存在某種奇怪的操作系統錯誤。

也許你有一個註冊表項對於你來說是不可見的,它是運行註冊表編輯器但不是你的代碼的用戶?權限問題可能是?您的代碼在Windows Vista或Server 2008中作爲高級用戶運行嗎?您是否嘗試以管理員身份運行註冊表編輯器?

+0

你也可以得到ERROR_PATH_NOT_FOUND – 2010-03-17 19:14:21

0

請注意,除了以「Reg」開頭的「核心」註冊表函數外,還有以「SHReg」開頭的輔助函數。這些文件適用於use by the Shell即Explorer,但有文檔記錄,並且也可用於普通應用程序。它們通常是很薄的包裝器,可以使一些常見任務更容易。它們是「Shell LightWeight API」的一部分(shlwapi.dll)