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;
        }
Example #2
0
        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);
 }