private void ChangeHandler(object sender, RegistryChangeEventArgs e) { Logger.Trace("ChangeHandler called for {DisableBasePath}", DisableBasePath); var newEnableStatus = GetCurrentEnableStatus(); foreach (var newStatus in newEnableStatus) { var name = newStatus.Key; var nowEnabled = newStatus.Value; var wasEnabled = true; if (lastEnableStatus.ContainsKey(name)) { wasEnabled = lastEnableStatus[name]; } if (wasEnabled != nowEnabled) { if (nowEnabled) { Enable?.Invoke(name); } else { Disable?.Invoke(name); } } } foreach (var lastStatus in lastEnableStatus) { var name = lastStatus.Key; var wasEnabled = lastStatus.Value; if (newEnableStatus.ContainsKey(name)) { continue; } if (!wasEnabled) { Enable?.Invoke(name); } } lastEnableStatus = newEnableStatus; }
private void MonitorThread() { try { IntPtr ptr = IntPtr.Zero; lock (this) { if (this._registryPath.StartsWith("HKEY_CLASSES_ROOT")) { this._monitorKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(this._registryPath.Substring(18)); } else if (this._registryPath.StartsWith("HKCR")) { this._monitorKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(this._registryPath.Substring(5)); } else if (this._registryPath.StartsWith("HKEY_CURRENT_USER")) { this._monitorKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(this._registryPath.Substring(18)); } else if (this._registryPath.StartsWith("HKCU")) { this._monitorKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(this._registryPath.Substring(5)); } else if (this._registryPath.StartsWith("HKEY_LOCAL_MACHINE")) { this._monitorKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(this._registryPath.Substring(19)); } else if (this._registryPath.StartsWith("HKLM")) { this._monitorKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(this._registryPath.Substring(5)); } else if (this._registryPath.StartsWith("HKEY_USERS")) { this._monitorKey = Microsoft.Win32.Registry.Users.OpenSubKey(this._registryPath.Substring(11)); } else if (this._registryPath.StartsWith("HKU")) { this._monitorKey = Microsoft.Win32.Registry.Users.OpenSubKey(this._registryPath.Substring(4)); } else if (this._registryPath.StartsWith("HKEY_CURRENT_CONFIG")) { this._monitorKey = Microsoft.Win32.Registry.CurrentConfig.OpenSubKey(this._registryPath.Substring(20)); } else if (this._registryPath.StartsWith("HKCC")) { this._monitorKey = Microsoft.Win32.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; } Logger.Trace("Monitoring of {Path}", _registryPath); // RegNotifyChangeKeyValue blocks until a change occurs. int result = RegNotifyChangeKeyValue(ptr, true, this._filter, IntPtr.Zero, false); Logger.Trace("Handling monitoring event of {Path}", _registryPath); if ((this._monitorThread == null) || (this._monitorKey == null)) { break; } if (result == 0) { Logger.Trace("Change detected on {Path}", _registryPath); if (this.Changed != null) { RegistryChangeEventArgs e = new RegistryChangeEventArgs(this); this.Changed(this, e); if (e.Stop) { break; } } } else { Logger.Trace("Error on monitoring of {Path}", _registryPath); 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); } } }
private void ErrorHandler(object sender, RegistryChangeEventArgs e) { Logger.Error("Error on monitoring of {DisableBasePath}: {@Exception}", DisableBasePath, e); }