Do you want your application to be notified when there is a change in the Windows Registry? Do you need to watch a specific value in the Registry and get notified when it is changed/deleted/renamed? If yes, you can use the component presented in this article.

The Registry provider supplies four event classes for events in the system Registry. All of them reside in the root\DEFAULT namespace. The Registry event classes in WMI are: RegistryEvent, RegistryTreeChangeEvent, RegistryKeyChangeEvent, and RegistryValueChangeEvent. Here is a short description of these classes: RegistryEvent is an abstract base class for changes in the Registry. RegistryTreeChangeEvent is a class that monitors changes to a hierarchy of keys. RegistryKeyChangeEvent monitors changes to a single key. RegistryValueChangeEvent monitors changes to a single value. All these classes have a property called Hive that identifies the hierarchy of keys to be monitored for change. HKEY_CLASSES_ROOT and HKEY_CURRENT_USERare not supported by these classes and changes can not be detected.

In order to receive events asynchronously, you should subscribe to the EventArrived event of the ManagementEventWatcher class instead of calling the WaitForNextEvent method which blocks the thread. After subscribing to the event, you should call the Start method of the ManagementEventWatcher class. Calling the Stop method will stop listening to events. The event is fired when a new WMI event arrives. Data about the event can be retrieved through the NewEvent property of the EventArrivedEventArgs class. Here is how it works:

Strongly-typed WMI classes can be generated by using the Mgmtclassgen.exe tool which is included in the .NET Framework SDK. Every property and every method in the WMI class has an equivalent property and method in the generated class. These are the classes generated by this tool: RegistryEvent, RegistryKeyChangeEvent, RegistryTreeChangeEvent, and RegistryValueChangeEvent. They can be found in the WMI classes folder.

In order to get notified when the Registry changes, you do not need to create the query yourself and subscribe to the event. You just pass the Hive and KeyPath you want to watch, to the component presented in this article. The component consists of an abstract class RegistryChangeBase which inherits from ManagementEventWatcher. There are three classes inheriting from RegistryChangeBase: RegistryKeyChange, RegistryTreeChange, and RegistryValueChange. All of these classes provide an event which is raised when the corresponding event is detected by WMI. This is how it all works:

As you can see from the above code, the constructor of the class calls a method that builds the query string and sets up the event handler for the EventArrived event. In the event handler, it uses the data of the event to create a new instance of the RegistryKeyChangeEvent class which is a strongly typed wrapper around the WMI class. After that, it just raises the event if there are any subscribers. Other classes inheriting from RegistryChangeBase are designed in the same way.

When building queries for receiving WMI events, the where clause must contain the values for every property in the specified event class. Moreover, the system Registry provider must be able to build a list of possible values for each property. Here are some examples:

When I initially published the article, the component worked on Vista but not on XP. This was really strange as usually things break on Vista and work on XP but not the other way around. In his comment Uros Calakovic posted how to make the component work in XP. The only thing that I changed is adding the following line to constructor of RegistryChangeBase class:

Using the classes should be quite straightforward. Just choose the class you need according to what kind of notification you need to receive, create an instance, subscribe to the RegistryXXXChanged event, and call the Start method to start receiving notification. Here is an example:

As the events are fired asynchronously, you cannot access controls created by other threads directly. Note that the parameter of the event handler is an instance of the strongly typed WMI class. Also note the use of the TIME_CREATED property to retrieve the time when the event was generated. To stop receiving notifications, just call Stop method.

Constructors that accept List<String> as one of the parameters can be used to build queries like this:

Comments and Discussions

Maybe it's just me, but I reckon the concept of registry is fairly unfriendly to both developers and end users. So many mishaps happen because the registry is corrupted or out of sync with the program that I see it as a major pain in the behind, and certainly something to stay away from at all costs when programming .NET. Just my two cents