As I've noted before, the System.Management namespace has a lot of WMI-related goodies in it. In particular it includes analogues for the RegistryTreeChangeEvent, RegistryKeyChangeEvent and RegistryValueChangeEvent behaviours.
You can get at them as follows
- Create a suitable System.Management.ManagementScope object -- e.g. scope = new ManagementScope("root\\default");
- Create a new WqlEventQuery, call it q, and set the EventClass like q.EventClassName = "RegistryValueChangeEvent";
- Set the appropriate condition depending on the event class --
- For Tree change q.Condition = "Hive='HKEY_LOCAL_MACHINE' and RootPath='Software\\\\RavnaAndTines' ";
- For Key change q.Condition = "Hive='HKEY_LOCAL_MACHINE' and KeyPath='Software\\\\RavnaAndTines' ";
- For Value change q.Condition = "Hive='HKEY_LOCAL_MACHINE' and KeyPath='Software\\\\RavnaAndTines' and ValueName='my key'";
- Create a ManagementEventWatcher(scope, q) and add an appropriate EventArrivedEventHandler to the EventArrived property
- Start() the watcher (probably in its own thread, unless you can create it before the application main loop).
- As part of application termination, Stop() the watcher and Dispose() it.
Alternatively, the WqlEventQuery query string could be set manually, in which case it would be of form like
select * from RegistryTreeChangeEvent where Hive='HKEY_LOCAL_MACHINE' and RootPath='Software\\RavnaAndTines'
Presumably with more SQL-fu one could build a portmanteau query to look at multiple events, rather than creating one watcher per key or value.
The event handler looks like EventArrived(object sender, EventArrivedEventArgs e); the latter argument's NewEvent property is a name/value collection representing the WMI event, like
For Tree change
Hive = HKEY_LOCAL_MACHINE RootPath = Software\RavnaAndTines SECURITY_DESCRIPTOR = TIME_CREATED = 128351151930418266
For Key change
Hive = HKEY_LOCAL_MACHINE KeyPath = Software\RavnaAndTines SECURITY_DESCRIPTOR = TIME_CREATED = 128351153191840662
For Value change
Hive = HKEY_LOCAL_MACHINE KeyPath = Software\RavnaAndTines SECURITY_DESCRIPTOR = TIME_CREATED = 128351161584291834 ValueName = my key
and can obviously be common code for all watcher objects
IronPython script used for rapid prototyping/validation
File System watching
This is much simpler, in that the behaviour is kept into one object (System.IO.FileSystemWatcher). there are complexities about multi-threading (if the object is being invoked in conjunction with UI objects); and for handling situations where there is a high frequency of changes expected (by configuring how much space to devote to buffering events).
The FileSystemWatcher is supplied with a directory path, a flag to say whether it should recurse through sub-directories, and a simple filter string to determine which files to watch. Event handlers are then added to the appropriate property (Changed, Created, Deleted, Renamed). The object is then enabled by setting its EnableRaisingEvents property.
The object is, like the ManagementEventWatcher, an IDisposable, but is stopped by clearing the EnableRaisingEvents property.
The event handler looks like EventArrived(object sender, FileSystemEventArgs e); this gives the type of event and the path and name of the file (the new name in the case of a rename, the object being sub-typed to also have an old name and old path property).