IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Discussion :

RegEnumKeyEx et RegDeleteKey


Sujet :

Windows

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 140
    Points : 49
    Points
    49
    Par défaut RegEnumKeyEx et RegDeleteKey
    Bonjour,

    Je cherche à écrire une fonction qui aurait pour but de supprimer toutes les sous-clés d'une clé, à condition bien sûr que les sous-clés ne contiennent pas elles-même des sous-clés.

    Je n'y arrive que partiellement, je m'explique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    void DeleteSubkeysOfOneKey(HKEY hKey, struct s_registre *ptr_registre)
    {
      HKEY            hKeyDelSubkey;
      DWORD           retCode;
      DWORD           cSubKeys;
      int           i;
      DWORD           cbName;
      TCHAR           achKey[MAX_KEY_LENGTH];
    
      retCode = RegQueryInfoKey(hKey, NULL,
          NULL,
          NULL,
          &cSubKeys,
          NULL,
          NULL,
          NULL,
          NULL,
          NULL,
          NULL,
          NULL);
    
        if (cSubKeys != 0)
          {
            for (i=0; i<cSubKeys; i++)
              {
                cbName = MAX_KEY_LENGTH;
                retCode = RegEnumKeyEx(hKey, i,
                         achKey,
                         &cbName,
                         NULL,
                         NULL,
                         NULL,
                         NULL);
    
                if (retCode == ERROR_SUCCESS)
                  {
                    retCode = RegDeleteKey(hKey, achKey);
                    if (retCode != ERROR_SUCCESS)
                      {
                        printf("%s\\%s\n", ptr_registre->handle, achKey);
                        printf("  error : deletion of this subkey failed...\n");
                      }
                    else
                      printf("Deleted !\n");
                 }
                else
                  printf("Subkey%d=%s\\%s\\%s\n\n\n", i, ptr_registre->handle, ptr_registre->path, achKey);
             }
         }
    }
    Je cherche à supprimer les cinq sous-clé a, b, c, d, e de la clé TEST :

    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\TEST\a
    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\TEST\b
    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\TEST\c
    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\TEST\d
    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\TEST\e
    Et j'obtiens ça comme résultat à l'écran :

    Subkey0=Deleted !
    Subkey1=Deleted !
    Subkey2=Deleted !
    Subkey3=HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\TEST\e
    Subkey4=HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\TEST\e
    Et donc deux sous-clés ne sont pas supprimées :

    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\TEST\b
    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\TEST\d
    En gros, une sous-clé sur deux n'est pas supprimée... pourtant, lorsque je lis les clés, avec la même boucle for que ci-dessus, j'obtiens :

    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\TEST\a
    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\TEST\b
    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\TEST\c
    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\TEST\d
    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\TEST\e
    Je ne comprends pas comment la fonction RegEnumKeyEx peut changer de comportement alors que le code est strictement identique.

    Merci par avance de votre aide.


  2. #2
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Merillym Voir le message
    Je ne comprends pas comment la fonction RegEnumKeyEx peut changer de comportement alors que le code est strictement identique.
    Tout simplement parce que tu es en train de supprimer des éléments d'une liste que tu es également en train d'énumérer...

    Il te faut mémoriser les clés dans un premier temps, et APRÈS avoir fini l'énumération, les supprimer.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 140
    Points : 49
    Points
    49
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    Tout simplement parce que tu es en train de supprimer des éléments d'une liste que tu es également en train d'énumérer...

    Il te faut mémoriser les clés dans un premier temps, et APRÈS avoir fini l'énumération, les supprimer.
    Ah vi je comprends.

    Donc on liste d'abord et après on supprime : on ne peut pas lister une sous-clé, la supprimer, et en lister une autre.

    Merci

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 140
    Points : 49
    Points
    49
    Par défaut
    Re,

    Juste une dernière petite question : quand tu dis mémoriser, cela signifie, par exemple, enregistrer chaque sous-clé dans un tableau de type char. Ensuite, je lis un à un chaque tableau et j'applique la suppression. Est-ce bien ce que tu entendais par "mémoriser" ?

    Merci.

  5. #5
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Merillym Voir le message
    on ne peut pas lister une sous-clé, la supprimer, et en lister une autre.
    Ce serait éventuellement possible, mais ces fonctions ne le permettent pas : à la suppression d'une clé, tu invalides les pointeurs internes, donc le RegEnum effectué après la première suppression est déjà, normalement, totalement foireux... Je te laisse imaginer après N suppressions !!
    C'est le problème de la suppression d'un élément dans un tableau : après avoir supprimé l'élément et "compacté" le tableau, si tu continues ton parcours sur les indices non-modifiés, tu as "sauté" un élément car tu n'aurais pas dû incrémenter le pointeur.
    Sur les listes chaînées, c'est le problème de mémoriser le parent qui se pose : tu peux perdre cette notion à la suppression, et donc casser ta liste.

    La fonction RegEnum est générique : elle est aussi bien utilisable pour la consultation de la base de registre que pour sa modification. Or, pour des questions de performances très certainement, elle ne vérifie pas son contexte d'appel en appel... Cela permet d'aller plus vite pour la consultation "normale", mais ça rend impossible la suppression simultanée.

    Citation Envoyé par Merillym Voir le message
    Est-ce bien ce que tu entendais par "mémoriser" ?
    Tout à fait, bien que pour des raisons de praticité, tu puisses utiliser à la place d'un tableau "en dur" un container un peu évolué et libérant tout seul ses éléments, comme un std::vector par exemple.

    Mais cela reste parfaitement faisable avec du code C bête et méchant : si tu ne stockes dedans que des pointeurs vers des chaines, un realloc de ton tableau ne coûtera pas "cher" en temps CPU, car il restera relativement petit quoi qu'il en soit.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 140
    Points : 49
    Points
    49
    Par défaut
    Re Mac Lak,

    Merci pour toutes ces précisions très intéressantes.

    Actuellement, je me limite au C et ne compte pas apprendre un nouveau langage tout de suite, même le C++, afin d'acquérir de solides bases.

    si tu ne stockes dedans que des pointeurs vers des chaines, un realloc de ton tableau ne coûtera pas "cher" en temps CPU, car il restera relativement petit quoi qu'il en soit.
    Je comptais partir sur quelque chose de ce genre, mais j'ai du mal à mettre cela en place.

    En fait le but n'est pas de supprimer les sous-clés d'une clé, mais de tout supprimer, clés, sous-clés et valeurs d'une clé. Je cherche à faire un équivalent de REG DELETE "clé à supprimer". J'y suis presque, mais me reste ce problème à résoudre.

    Je cherche comment stocker mes chaînes après chaque énumération...


  7. #7
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Merillym Voir le message
    Je cherche comment stocker mes chaînes après chaque énumération...
    Déjà, RegQueryInfoKey te permettra de savoir la taille de la plus grande clé (paramètre lpcMaxSubKeyLen), donc de dimensionner la taille de tes malloc unitaires.
    Via le paramètre lpcSubKeys, tu auras également le nombre de sous-clés dedans, ce qui peut donc te permettre d'avoir, directement, le nombre de chaînes à allouer et leur taille. Après, un simple strcpy pendant l'énumération suffira.

    Théoriquement, on peut se passer d'une mémorisation en gérant correctement le paramètre dwIndex de RegEnumKeyEx, mais si tu n'as pas trop familier avec des concepts tels que la suppression pendant le parcours dans une liste, il vaut certainement bien mieux le faire "à la barbare" dans un premier temps afin de bien comprendre les fonctions utilisées. Tu pourras toujours améliorer ça après, ce sera d'ailleurs très formateur pour toi, mais au moins tu auras ta fonction disponible au plus vite possible.

    EDIT : Je dis bien "théoriquement", au fait, car tu n'as pas la certitude que l'implémentation des fonctions d'énumération ne changera pas. Je te rappelle que la base de registre, par exemple, ne permet pas de garantir la position (=l'index) d'une clé nouvellement créée, car il n'y a pas de "compactage" des index lors d'une suppression et la création d'une clé utilise le premier numéro d'index libre.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 140
    Points : 49
    Points
    49
    Par défaut
    Re,

    Ok, je vais commencer par faire "à la barbare" comme tu dis et après j'essayerais d'optimiser au mieux.

    Je te rappelle que la base de registre, par exemple, ne permet pas de garantir la position (=l'index) d'une clé nouvellement créée, car il n'y a pas de "compactage" des index lors d'une suppression et la création d'une clé utilise le premier numéro d'index libre.
    Oui merci du rappel.

    Via le paramètre lpcSubKeys, tu auras également le nombre de sous-clés dedans, ce qui peut donc te permettre d'avoir, directement, le nombre de chaînes à allouer et leur taille. Après, un simple strcpy pendant l'énumération suffira.
    Oui mais comme je fais appel à la récursivité pour obtenir toutes les sous-clés ( un peu comme un REG QUERY clé /s ), je ne peux pas avoir le nombre de chaînes à allouer avant d'avoir eu les infos de la dernière sous-clé rencontrée.

    Je pense que je peux parcourir toutes les sous-clés une fois pour obtenir les informations, une deuxième fois pour obtenir les chaînes et les allouer. Et après je supprime une à une toutes les clés.

    De toutes façons, sur mon dual core E5200, ça met moi d'un centième de seconde pour boucler une fois, donc je peux bien le faire deux fois, je ne suis pas pour le moment à un centième de seconde prêt.

    Mais bon, c'est sûr que ce n'est pas très "propre".

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 140
    Points : 49
    Points
    49
    Par défaut
    Re,

    J'y suis presque mais j'ai un souci lors du remplissage de mon tableau à deux dimensions de type char.

    J'ai exposé le problème ici : http://www.developpez.net/forums/d85...ues-problemes/


+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Probléme RegOpenKeyEx & RegEnumKeyEx
    Par Invité dans le forum Windows
    Réponses: 2
    Dernier message: 03/05/2013, 09h45
  2. Problème de lecture registre avec RegEnumKeyEx
    Par mdriesbach dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 28/10/2005, 11h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo