1: // P/Invoke methods and constants
2:
3: internal class NativeMethods
4: {
5: private NativeMethods()
6: {
7: }
8:
9: [DllImport("advapi32.dll", SetLastError = true)]
10: internal static extern int RegNotifyChangeKeyValue(
11: IntPtr hKey,
12: [MarshalAs(UnmanagedType.Bool)]
13: bool watchSubtree,
14: int dwNotifyFilter,
15: IntPtr hEvent,
16: [MarshalAs(UnmanagedType.Bool)]
17: bool fAsynchronous
18: );
19:
20: [DllImport("advapi32.dll", SetLastError = true)]
21: internal static extern int RegOpenKeyEx(
22: IntPtr hKey,
23: string subKey,
24: uint options,
25: int sam,
26: out IntPtr phkResult
27: );
28:
29: [DllImport("advapi32.dll", SetLastError = true)]
30: internal static extern int RegCloseKey(
31: IntPtr hKey
32: );
33:
34: internal const int HKEY_CLASSES_ROOT = unchecked((int)0x80000000);
35: internal const int HKEY_CURRENT_USER = unchecked((int)0x80000001);
36: internal const int HKEY_LOCAL_MACHINE = unchecked((int)0x80000002);
37: internal const int HKEY_USERS = unchecked((int)0x80000003);
38: internal const int HKEY_PERFORMANCE_DATA= unchecked((int)0x80000004);
39: internal const int HKEY_CURRENT_CONFIG = unchecked((int)0x80000005);
40: internal const int HKEY_DYN_DATA = unchecked((int)0x80000006);
41:
42: internal const int KEY_NOTIFY = 0x0010;
43:
44: internal const int REG_NOTIFY_CHANGE_NAME = 0x00000001;
45: internal const int REG_NOTIFY_CHANGE_ATTRIBUTES = 0x00000002;
46: internal const int REG_NOTIFY_CHANGE_LAST_SET = 0x00000004;
47: internal const int REG_NOTIFY_CHANGE_SECURITY = 0x00000008;
48: }
49:
50: .................................
51:
52: IntPtr parentKey = new IntPtr(NativeMethods.HKEY_LOCAL_MACHINE);
53:
54: string subKey = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify\TestKey"
55:
56: IntPtr monitoredKey;
57:
58: try
59: {
60: int ret = NativeMethods.RegOpenKeyEx(parentKey, subKey, 0, NativeMethods.KEY_NOTIFY, out monitoredKey);
61: if (ret != 0)
62: {
63: throw new Win32Exception(ret);
64: }
65:
66: using (AutoResetEvent monitorEvent = new AutoResetEvent(false))
67: {
68: ret = NativeMethods.RegNotifyChangeKeyValue(parentKey, true,
69: NativeMethods.REG_NOTIFY_CHANGE_NAME | NativeMethods.REG_NOTIFY_CHANGE_ATTRIBUTES |
70: NativeMethods.REG_NOTIFY_CHANGE_LAST_SET | NativeMethods.REG_NOTIFY_CHANGE_SECURITY,
71: monitorEvent.Handle, true);
72:
73: if (ret != 0)
74: {
75: throw new Win32Exception(ret);
76: }
77:
78: monitorEvent.WaitOne();
79: // Do something after the registry has changed
80: }
81: }
82: finally
83: {
84: parentKey = IntPtr.Zero;
85: if (monitoredKey != IntPtr.Zero)
86: {
87: NativeMethods.RegCloseKey(monitoredKey);
88: monitoredKey = IntPtr.Zero;
89: }
90: }