2011-09-29 54 views
1

我在做一個應用程序,我需要在註冊表中編寫一些東西,稍後編輯它們,如果需要的話。我正在使用KEY_WOW64_64KEY寫入64位註冊表。我創建了我的Key Software \ MyApp,並在這裏創建了一些其他值5或6.我的問題如下。我有以下代碼來讀取每一個值,下一個關鍵如何從XP下的64位註冊表中刪除?

void ReadAndDeleteValues(HKEY hKey) 
{ 

//TCHAR achKey[ MAX_KEY_LENGTH ];  // buffer for subkey name 
//DWORD cbName;       // size of name string 
TCHAR achClass[ MAX_PATH ] = TEXT(""); // buffer for class name 
DWORD cchClassName = MAX_PATH;   // size of class string 
DWORD cSubKeys=0;      // number of subkeys 
DWORD cbMaxSubKey;      // longest subkey size 
DWORD cchMaxClass;      // longest class string 
DWORD cValues;       // number of values for key 
DWORD cchMaxValue;      // longest value name 
DWORD cbMaxValueData;     // longest value data 
DWORD cbSecurityDescriptor;    // size of security descriptor 
FILETIME ftLastWriteTime;     // last write time 

DWORD i, retCode; 

TCHAR achValue[ MAX_VALUE_NAME ]; 
DWORD cchValue = MAX_VALUE_NAME; 

// Get the class name and the value count. 
retCode = RegQueryInfoKey(
          hKey,     // key handle 
          achClass,    // buffer for class name 
          &cchClassName,   // size of class string 
          NULL,     // reserved 
          &cSubKeys,    // number of subkeys 
          &cbMaxSubKey,   // longest subkey size 
          &cchMaxClass,   // longest class string 
          &cValues,    // number of values for this key 
          &cchMaxValue,   // longest value name 
          &cbMaxValueData,   // longest value data 
          &cbSecurityDescriptor, // security descriptor 
          &ftLastWriteTime   // last write time 
         ); 

if (cValues > 0) printf("\nNumber of values: %d\n", cValues); 

for (i = 0, retCode = ERROR_SUCCESS; i < cValues; i++) 
{ 
    cchValue = MAX_VALUE_NAME; 
    achValue[ 0 ] = '\0'; 

    retCode = RegEnumValue(hKey, 
          i, 
          achValue, 
          &cchValue, 
          NULL, 
          NULL, 
          NULL, 
          NULL 
         ); 

    if (retCode == ERROR_SUCCESS) 
    { 

     DWORD cbData = 8192; 
     DWORD dwRet; 
     DWORD type = 0; 
     wchar_t PerfData[ 2048 ] = { 0 }; 

     memset(PerfData, 0, wcslen(PerfData)); 

     dwRet = RegQueryValueEx(hKey, 
           achValue, 
           NULL, 
           &type, 
           (LPBYTE)PerfData, 
           &cbData 
           ); 

     if (dwRet == ERROR_SUCCESS) ;//do nothing 
     else printf("\n\nRegQueryValueEx Failed!"); 

     _tprintf(TEXT("\n #%.3d - [ %-30s ]"), i + 1, achValue); 

     RegDeleteValue(hKey, achValue); 

    }//if 
}//for 

} // ReadValues

它工作正常,所以我想,我只是把RegDeleteValue那裏,每個值都將被刪除。不幸的是,這不是發生了什麼事情。該API將只刪除2-3個值,然後返回。如果我再次運行它,那麼它會再次刪除2-3個值並再次返回,但我不知道爲什麼?理論上,如果我找到一個價值,我可以刪除,所以我不明白,爲什麼會發生這種情況。

有人能幫我糾正我的代碼嗎?

謝謝!

+1

當Windows API調用失敗時,調用GetLastError()來確定失敗原因通常是個好主意。 – Ferruccio

+0

並實際*測試*返回值並報告失敗。 –

回答

3

你的程序刪除,因爲經典的「刪除從數組」錯誤的只有幾個值,像這樣的僞代碼:

// this program will not remove all elements 
for (int i = 0, n = arraySize; i < n; ++i) 
    array_remove(array, i); 

// step 1, i=0: 1 2 3 4 5 6 
//   ^removed 
// step 2, i=1: 2 3 4 5 6 
//    ^removed 
// step 3, i=2: 2 4 5 6 
//    ^removed 
// step 4, i=3: 2 4 6 
//     ^RegEnumValue returns error and the loop exits 

以正確的方式將是這樣的:

while (cValues > 0) { 
    /* delete registry value at index 0 */ 
    --cValues; 
} 

要快速修復您的代碼,將RegEnumValue()的第二個參數替換爲0

+0

「RegEnumValue」文檔中明確指出了這一點:「在使用RegEnumValue時,應用程序不應調用任何可能會改變被查詢關鍵字的註冊表函數。」 http://msdn.microsoft.com/en-us/library/ms724865.aspx –

+0

@Eugene Homaykov:非常感謝。我怎麼會想念那個?無論如何,這真的解決了我的問題! – kampi