2011-09-29 2 views
1

Je fais une application, et j'ai besoin d'écrire des choses dans le registre, et les éditer plus tard si nécessaire. J'écris dans le registre 64 bits en utilisant KEY_WOW64_64KEY. J'ai créé mon logiciel clé \ MyApp et voici d'autres valeurs 5 ou 6. Mon problème est le suivant. J'ai le code suivant pour lire toutes les valeurs, sous une cléComment supprimer du registre 64 bits sous XP?

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

Il fonctionne très bien, donc je pensais, je place juste là RegDeleteValue et chaque valeur seront effacés. Malheureusement, ce n'est pas ce qui se passe. Cette API supprimera seulement 2-3 valeurs, puis retournera. Si je l'exécute à nouveau, alors il va supprimer à nouveau les valeurs 2-3 et revient à nouveau, mais je ne sais pas pourquoi ???? Théoriquement si je trouve une vallée, je peux supprimer, donc je ne comprends pas, pourquoi cela se produit-il.

Quelqu'un pourrait m'aider à corriger mon code?

Merci!

+1

Lorsqu'un appel de l'API Windows échoue, il est généralement recommandé d'appeler GetLastError() pour déterminer la cause de l'échec. – Ferruccio

+0

Et pour réellement * tester * renvoyer des valeurs et signaler un échec. –

Répondre

3

Votre programme supprime seulement quelques valeurs en raison de la classique « suppression du tableau » erreur, comme dans ce pseudo-code:

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

Une bonne façon sera quelque chose comme:

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

Pour corrigez rapidement votre code, remplacez le second paramètre de RegEnumValue() par 0.

+0

Ceci est explicitement appelé dans la documentation de 'RegEnumValue':" Lors de l'utilisation de RegEnumValue, une application ne devrait appeler aucune fonction de registre susceptible de modifier la clé demandée. " http://msdn.microsoft.com/en-us/library/ms724865.aspx –

+0

@Eugene Homaykov: Merci beaucoup. Comment pourrais-je manquer ça? Merci quand même, ça a vraiment réglé mon problème! – kampi

Questions connexes