如何从XP下的64位注册表中删除?

问题描述:

我在做一个应用程序,我需要在注册表中编写一些东西,稍后编辑它们,如果需要的话。我正在使用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

并实际*测试*返回值并报告失败。 –

你的程序删除,因为经典的“删除从数组”错误的只有几个值,像这样的伪代码:

// 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