24

I'm a newbie to WMI and I need to implement RegistryValueChangeEvent in a C# service.

I need an event handler that gets triggered each time any one of a set of registry values is changed. I want behavior similar to the FileSystemWatcher class's Changed event, but for registry values.

If there's some other technique I could use to accomplish the same task, I'd appreciate that as well. My minimum requirement is that it be a better solution than what I have now: polling every 20 seconds and comparing the registry value with the last result.

Please provide example code in your answer. If I can get an example for watching just one registry value, that would be fine.

I need a solution in .Net 2.0

Thanks.

Andrew Ensley
  • 11,611
  • 16
  • 61
  • 73

4 Answers4

32

WMI can sometimes be interesting to work with...I think I understand your question, so take a look at the code snippet below and let me know if it's what you're looking for.

// --------------------------------------------------------------------------------------------------------------------- 
// <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();
        }
    }
}
Ed Altorfer
  • 4,373
  • 1
  • 24
  • 27
  • That's exactly what I'm looking for. I'll try it out and let you know how it works. – Andrew Ensley May 11 '09 at 19:25
  • 1
    Great, Andrew. Let me know if you have any trouble re-purposing it for your own use. You can ping me on AIM if you want--e4lt0rf3R (replace the numbers with letters). I will be happy to help you resolve any additional questions you have and then post a summary of them here. – Ed Altorfer May 11 '09 at 19:47
  • 1
    Sorry for commenting an "old" answer, but, is there a way through that example that works for HKEY_CURRENT_USER – SomeNickName Apr 18 '14 at 19:38
  • It doesn't tell me exactly _what_ has changed, only that the defined event has triggered. Not quite what a FileSystemWatcher can do. – ygoe Sep 17 '14 at 21:39
  • Can you give an entire class of registry monitoring? It's from here? [RegistryMonitor](https://www.codeproject.com/Articles/4502/RegistryMonitor-a-NET-wrapper-class-for-RegNotifyC) ? – GooliveR Jun 28 '17 at 13:49
  • @AndrewEnsley I ran this code but how can i trigger this event – Ijas May 05 '20 at 12:15
  • @Ed Altorfer I opened regedit.exe and edited key but event is not triggering – Ijas May 05 '20 at 12:17
4

You really don't need WMI, as others have pointed out. I too have used RegistryMonitor with no problems.

If you need an example, there's already example code for the RegistryMonitor on the page itself. Did you scroll down to this bit on the code project:

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");
    }
}
Dan
  • 2,338
  • 17
  • 28
  • 2
    Yes I did, but... it doesn't meet the requirements of my question. I need example code for an event that gets fired when a specific registry _VALUE_ is changed; not a key. I understand I can get that from RegistryMonitor, but if someone wants to save my time, they have a lot to gain. – Andrew Ensley May 14 '09 at 02:25
3

Are you limited to WMI? If not you can use RegNotifyChangeKeyValue wrappers like RegistryMonitor

Sudhanshu Mishra
  • 6,523
  • 2
  • 59
  • 76
felixg
  • 974
  • 1
  • 9
  • 10
  • No I am not limited to WMI, that's just the only method I knew of at the time of posting. Thanks for the links. They are helpful. Could you provide some example code though? – Andrew Ensley May 11 '09 at 19:20
  • 4
    Let's not be rude, guys. The question asked for example code; also, one must bear in mind that some links become stale and example code will be archived here for the foreseeable future. :) – Ed Altorfer May 14 '09 at 06:29
  • @Dave short answer, and what no one else has said - yes, he is that lazy. that's not a bad thing. – TheSoftwareJedi May 17 '09 at 00:26
  • 1
    @TheSoftwareJedi: Read my comment on a similar answer below. The source code and examples given on that project page DO NOT meet the requirements of my question. Registry Monitor only watches for changes to _KEYS_. Any change to any subkeys or values will fire the event handler. I need an event handler for when a registry _VALUE_ changes. Before anyone calls me lazy, they should take the time to actually read the question. /rant – Andrew Ensley May 17 '09 at 16:00
  • Like it's been mentioned, the RegistryMonitor link has become stale. The new link for the CodeProject article is http://www.codeproject.com/Articles/4502/RegistryMonitor-a-NET-wrapper-class-for-RegNotifyC – Sudhanshu Mishra Jun 12 '15 at 01:42
0

You'll need to utilize WMI for it. See http://msdn.microsoft.com/en-us/library/aa393035.aspx

marcc
  • 12,295
  • 7
  • 49
  • 59