2012-01-15 1 views
3

J'essaie d'utiliser RegNotifyChangeKeyValue pour surveiller les modifications d'une clé de registre 64 bits. Pour ouvrir cette clé à partir d'une application 32 bits, nous devons ajouter l'indicateur d'accès KEY_WOW64_64KEY.Utilisez RegNotifyChangeKeyValue pour surveiller les modifications apportées à une clé 64 bits

Malheureusement, je ne peux pas sembler être en mesure de surveiller les changements à cette clé, seulement son homologue de 32 bits.

J'inclus un projet de démonstration avec l'unité que j'utilise pour implémenter la surveillance du registre. Téléchargez-le ici: RegMonitor

Étapes pour reproduire le problème:

  1. recompiler le programme. Exécuter en tant qu'administrateur. Cliquez sur le bouton Démarrer.

  2. Ouvrez regedit et accédez à

    HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Run

  3. Ajouter une nouvelle valeur là-bas. RegMonitor ne détectera aucun changement.

  4. Accédez à

    HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft \ Windows \ CurrentVersion \ Run

  5. Ajouter une nouvelle valeur là-bas. RegMonitor détectera ce changement.

J'ai ajouté le drapeau d'accès KEY_WOW64_64KEY lors de l'ouverture du registre, mais il n'a toujours pas de tout notify modifications pour corriger la clé, seule la redirection Wow6432Node.

Une idée s'il est possible d'utiliser RegNotifyChangeKeyValue pour surveiller cette clé?

+1

OK, j'ai créé l'exemple d'application à partir d'ici: http://msdn.microsoft.com/en-us/library/windows/desktop/ms724892(v=vs.85).aspx Ensuite, je l'ai modifié pour utiliser ' KEY_WOW64_64KEY' lors de l'ouverture de la clé. Et puis le code m'a notifié avec succès d'un changement dans la partie 64 bits du registre. Donc non, l'API fonctionne bien avec 'KEY_WOW64_64KEY' de l'émulateur. –

+0

En aparté, vous avez codé en dur 'Wow6432Node' dans votre application. C'est toujours une mauvaise idée. Je crois que cela a été fait uniquement dans le but de tester cette application. –

+0

L'application de démonstration est juste à des fins de test, c'est pourquoi j'ai dur codé le drapeau dans celui-ci. – smartins

Répondre

2

L'exemple minimal suivant détecte les modifications dans la vue 64 bits du registre, à partir d'un processus 32 bits. Je ne sais pas ce qui est différent de votre programme, mais ce code prouve qu'un programme 32 bits peut effectivement détecter des changements dans les deux vues. Je sais que cela ne résout pas votre problème, mais j'espère que cela vous aidera à vous orienter dans la bonne direction.

program RegMonitor; 

{$APPTYPE CONSOLE} 

uses 
    SysUtils, Windows; 

procedure Main; 
const 
    dwFilter: DWORD = 
    REG_NOTIFY_CHANGE_NAME or 
    REG_NOTIFY_CHANGE_ATTRIBUTES or 
    REG_NOTIFY_CHANGE_LAST_SET or 
    REG_NOTIFY_CHANGE_SECURITY; 
var 
    Error: Integer; 
    key: HKEY; 
begin 
    Error := RegOpenKeyEx(
    HKEY_LOCAL_MACHINE, 
    'Software\Microsoft\Windows\CurrentVersion\RunOnce', 
    0, 
    KEY_NOTIFY or KEY_WOW64_64KEY, 
    key 
); 
    if Error<>ERROR_SUCCESS then 
    RaiseLastOSError(Error); 
    try 
    Error := RegNotifyChangeKeyValue(
     key, 
     True, 
     dwFilter, 
     0, 
     False 
    ); 
    if Error<>ERROR_SUCCESS then 
     RaiseLastOSError(Error); 
    Writeln('Change detected'); 
    Readln; 
    finally 
    RegCloseKey(key); 
    end; 
end; 

begin 
    Main; 
end. 

Maintenant, pour votre programme, il semble qu'il y ait beaucoup de problèmes avec elle. Mais le problème fondamental, celui qui signifie que vous n'êtes pas averti des changements, est que votre événement est créé incorrectement. Vous créez comme ceci:

CreateEvent(Nil, True, False, 'RegistryChangeMonitorEvent') 

mais vous devez créer comme ça

CreateEvent(nil, False, True, nil) 

Je n'ai pas fouillé dans quelles sont les exigences pour cet événement, la documentation ne fournit aucune indication. Tout ce que j'ai fait était de chercher les différences entre votre code et le code dans le MSDN example.

Apportez cette modification à la création d'événement et vous en avez assez pour commencer à recevoir des notifications.Cependant, quand j'ai fait ce changement, votre programme n'a toujours pas fonctionné et a échoué avec un AV. Un de vos objets n'a pas été créé. Cependant, je pense que ce sont des bugs assez routiniers que vous pouvez régler vous-même. Je demande pourquoi vous utilisez KEY_ALL_ACCESS. Pourquoi n'utilisez-vous pas KEY_NOTIFY lorsque vous ouvrez la clé pour passer à RegNotifyChangeKeyValue? Et quand vous essayez de construire un rapport de ce qui a changé dans une clé, pourquoi n'utilisez-vous pas KEY_READ? Puisque vous n'essayez pas d'écrire jamais, KEY_ALL_ACCESS n'est pas approprié. Si vous apportez ces modifications, vous n'aurez pas besoin d'exécuter en tant qu'administrateur.

+0

David, merci pour la réponse et toute l'enquête que vous avez faite jusqu'à présent. L'utilisation de KEY_ALL_ACCESS était uniquement à des fins de test. Je viens aussi d'essayer votre programme de démonstration, mais sur mon système il n'informe pas des changements sur HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ RunOnce, seulement sur HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft \ Windows \ CurrentVersion \ RunOnce Sur votre système, il détecte correctement les modifications sur la vue 64 bits de cette clé de registre? – smartins

+0

oui, sur mon système mon programme d'exemple détecte les changements dans la vue 64 bits. Je cours la victoire 7 x64 avec UAC et ne pas élever. Pas besoin de courir en tant qu'administrateur. –

+0

Il se peut que je manque quelque chose, mais ce code ne semble pas utiliser KEY_WOW64_64KEY, donc sûrement car il ne regarde que la vue 32 bits? –

Questions connexes