2009-05-05 25 views
18

Sono un principiante di WMI e devo implementare RegistryValueChangeEvent in un servizio C#.Registro Watcher C#

Ho bisogno di un gestore di eventi che viene attivato ogni volta che viene modificato un set di valori di registro. Voglio un comportamento simile all'evento Changed della classe FileSystemWatcher, ma per i valori del Registro di sistema.

Se c'è qualche altra tecnica che potrei usare per compiere lo stesso compito, lo apprezzerei anche io. Il mio requisito minimo è che sia una soluzione migliore di quella che ho ora: il polling ogni 20 secondi e il confronto del valore del registro con l'ultimo risultato.

Fornire il codice di esempio nella risposta. Se riesco a ottenere un esempio per la visualizzazione di un solo valore di registro, andrebbe bene.

Ho bisogno di una soluzione in Net 2.0

Grazie.

risposta

24

WMI a volte può essere interessante lavorare con ... Credo di capire la tua domanda, in modo da prendere uno sguardo al frammento di codice qui sotto e fatemi sapere se è quello che si' sto cercando.

// --------------------------------------------------------------------------------------------------------------------- 
// <copyright file="Program.cs" company=""> 
// 
// </copyright> 
// <summary> 
// Defines the WmiChangeEventTester type. 
// </summary> 
// --------------------------------------------------------------------------------------------------------------------- 
namespace WmiExample 
{ 
    using System; 
    using System.Management; 

    /// <summary> 
    /// </summary> 
    public class WmiChangeEventTester 
    { 
     /// <summary> 
     /// Initializes a new instance of the <see cref="WmiChangeEventTester"/> class. 
     /// </summary> 
     public WmiChangeEventTester() 
     { 
      try 
      { 
       // Your query goes below; "KeyPath" is the key in the registry that you 
       // want to monitor for changes. Make sure you escape the \ character. 
       WqlEventQuery query = new WqlEventQuery(
        "SELECT * FROM RegistryValueChangeEvent WHERE " + 
        "Hive = 'HKEY_LOCAL_MACHINE'" + 
        @"AND KeyPath = 'SOFTWARE\\Microsoft\\.NETFramework' AND ValueName='InstallRoot'"); 

       ManagementEventWatcher watcher = new ManagementEventWatcher(query); 
       Console.WriteLine("Waiting for an event..."); 

       // Set up the delegate that will handle the change event. 
       watcher.EventArrived += new EventArrivedEventHandler(HandleEvent); 

       // Start listening for events. 
       watcher.Start(); 

       // Do something while waiting for events. In your application, 
       // this would just be continuing business as usual. 
       System.Threading.Thread.Sleep(100000000); 

       // Stop listening for events. 
       watcher.Stop(); 
      } 
      catch (ManagementException managementException) 
      { 
       Console.WriteLine("An error occurred: " + managementException.Message); 
      } 
     } 

     /// <summary> 
     /// </summary> 
     /// <param name="sender"> 
     /// The sender. 
     /// </param> 
     /// <param name="e"> 
     /// The e. 
     /// </param> 
     private void HandleEvent(object sender, EventArrivedEventArgs e) 
     { 
      Console.WriteLine("Received an event."); 
      // RegistryKeyChangeEvent occurs here; do something. 
     } 

     /// <summary> 
     /// </summary> 
     public static void Main() 
     { 
      // Just calls the class above to check for events... 
      WmiChangeEventTester receiveEvent = new WmiChangeEventTester(); 
     } 
    } 
} 
+0

Questo è esattamente quello che sto cercando. Lo proverò e ti farò sapere come funziona. –

+0

Ottimo, Andrew. Fammi sapere se hai qualche problema a riproporlo per il tuo uso personale. Puoi mandarmi un ping su AIM se vuoi - e4lt0rf3R (sostituisci i numeri con le lettere). Sarò felice di aiutarti a risolvere eventuali ulteriori domande e di pubblicare qui un riepilogo di esse. –

+0

Ci scusiamo per aver commentato una "vecchia" risposta, ma c'è un modo per quell'esempio che funziona per HKEY_CURRENT_USER – SomeNickName

0

Avrete bisogno di utilizzare WMI per questo. Vedi http://msdn.microsoft.com/en-us/library/aa393035.aspx

+0

Ha ... lo so. Questa è la parte con cui ho bisogno di aiuto. –

+0

Ho cambiato la formulazione della mia domanda per riflettere ciò di cui ho veramente bisogno. Qualsiasi aiuto aggiuntivo? –

3

Sei limitato a WMI? Se non è possibile utilizzare involucri RegNotifyChangeKeyValue come RegistryMonitor

+0

No, non sono limitato a WMI, questo è solo l'unico metodo che conoscevo al momento della pubblicazione. Grazie per i link. Sono utili. Potresti fornire qualche codice di esempio? –

+1

Sei davvero così pigro che non puoi cliccare sul link RegistryMonitor e scaricare il file zip da CodeProject ?? –

+2

Non essere scortese, ragazzi. La domanda ha richiesto un codice di esempio; inoltre, si deve tenere presente che alcuni collegamenti diventano obsoleti e il codice di esempio verrà archiviato qui per il prossimo futuro. :) –

2

Davvero non c'è bisogno di WMI, come altri hanno fatto notare. Anch'io ho usato RegistryMonitor senza problemi.

Se è necessario un esempio, esiste già un codice di esempio per RegistryMonitor nella pagina stessa. Ti sei limitato a questo bit nel progetto del codice:

public class MonitorSample 
{ 
    static void Main() 
    { 
     RegistryMonitor monitor = new 
      RegistryMonitor(RegistryHive.CurrentUser, "Environment"); 
     monitor.RegChanged += new EventHandler(OnRegChanged); 
     monitor.Start(); 

     while(true); 

     monitor.Stop(); 
    } 

    private void OnRegChanged(object sender, EventArgs e) 
    { 
     Console.WriteLine("registry key has changed"); 
    } 
} 
+1

Sì, sì, ma ... non soddisfa i requisiti della mia domanda. Ho bisogno di codice di esempio per un evento che viene generato quando viene modificato uno specifico registro _VALORE_; non una chiave. Capisco che posso ottenerlo da RegistryMonitor, ma se qualcuno vuole risparmiare tempo, ha molto da guadagnare. –

Problemi correlati