private void RegistrySettingChanged(object sender, RegistryChangeEventArgs e) { if (!_resetting) { if (this.LastChanged.ContainsKey(e.Monitor.RegistryPath)) { if (DateTime.Now - this.LastChanged[e.Monitor.RegistryPath] < new TimeSpan(0, 0, 0, 2)) { return; } } _resetting = true; Log.Info("Registry setting changed at {0}. Resetting now.", e.Monitor.RegistryPath); e.Monitor.RegistrySettings.ForEach((registrySetting) => { RestoreRegistrySetting(registrySetting); }); this.LastChanged[e.Monitor.RegistryPath] = DateTime.Now; _resetting = false; } }
private void MonitorThread() { try { IntPtr ptr = IntPtr.Zero; lock (this) { if (this.RegistryPath.StartsWith("HKEY_CLASSES_ROOT")) { this._monitorKey = Registry.ClassesRoot.OpenSubKey(this.RegistryPath.Substring(18)); } else if (this.RegistryPath.StartsWith("HKCR")) { this._monitorKey = Registry.ClassesRoot.OpenSubKey(this.RegistryPath.Substring(5)); } else if (this.RegistryPath.StartsWith("HKEY_CURRENT_USER")) { this._monitorKey = Registry.CurrentUser.OpenSubKey(this.RegistryPath.Substring(18)); } else if (this.RegistryPath.StartsWith("HKCU")) { this._monitorKey = Registry.CurrentUser.OpenSubKey(this.RegistryPath.Substring(5)); } else if (this.RegistryPath.StartsWith("HKEY_LOCAL_MACHINE")) { this._monitorKey = Registry.LocalMachine.OpenSubKey(this.RegistryPath.Substring(19)); } else if (this.RegistryPath.StartsWith("HKLM")) { this._monitorKey = Registry.LocalMachine.OpenSubKey(this.RegistryPath.Substring(5)); } else if (this.RegistryPath.StartsWith("HKEY_USERS")) { this._monitorKey = Registry.Users.OpenSubKey(this.RegistryPath.Substring(11)); } else if (this.RegistryPath.StartsWith("HKU")) { this._monitorKey = Registry.Users.OpenSubKey(this.RegistryPath.Substring(4)); } else if (this.RegistryPath.StartsWith("HKEY_CURRENT_CONFIG")) { this._monitorKey = Registry.CurrentConfig.OpenSubKey(this.RegistryPath.Substring(20)); } else if (this.RegistryPath.StartsWith("HKCC")) { this._monitorKey = Registry.CurrentConfig.OpenSubKey(this.RegistryPath.Substring(5)); } // Fetch the native handle if (this._monitorKey != null) { object hkey = typeof(RegistryKey).InvokeMember( "hkey", BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic, null, this._monitorKey, null ); ptr = (IntPtr)typeof(SafeHandle).InvokeMember( "handle", BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic, null, hkey, null); } } if (ptr != IntPtr.Zero) { while (true) { // If this._monitorThread is null that probably means Dispose is being called. Don't monitor anymore. if ((this._monitorThread == null) || (this._monitorKey == null)) { break; } // RegNotifyChangeKeyValue blocks until a change occurs. int result = RegNotifyChangeKeyValue(ptr, true, this._filter, IntPtr.Zero, false); if ((this._monitorThread == null) || (this._monitorKey == null)) { break; } if (result == 0) { if (this.Changed != null) { RegistryChangeEventArgs e = new RegistryChangeEventArgs(this); this.Changed(this, e); if (e.Stop) { break; } } } else { if (this.Error != null) { Win32Exception ex = new Win32Exception(); // Unless the exception is thrown, nobody is nice enough to set a good stacktrace for us. Set it ourselves. typeof(Exception).InvokeMember( "_stackTrace", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.SetField, null, ex, new object[] { new StackTrace(true) } ); RegistryChangeEventArgs e = new RegistryChangeEventArgs(this); e.Exception = ex; this.Error(this, e); } break; } } } } catch (Exception ex) { if (this.Error != null) { RegistryChangeEventArgs e = new RegistryChangeEventArgs(this); e.Exception = ex; this.Error(this, e); } else { throw; } } finally { this.Stop(); } }