示例#1
0
        private object TryAddInternal(
            RegistryChangedEventHandler handler,
            RegistryChangedEventArgs args,
            out bool needNewThread
            )
        {
            WatchEntry newEntry;

            needNewThread = false;

            lock (_eventsLock) {
                if (_entries.Count >= MAXIMUM_WAIT_OBJECTS)
                {
                    needNewThread = true;
                    return(null);
                }
                newEntry = WatchEntry.TryCreate(handler, args);
                if (newEntry == null)
                {
                    return(null);
                }
                _entries.Add(newEntry);
            }

            _itemAdded.Set();

            return(newEntry);
        }
示例#2
0
        /// <summary>
        /// Starts listening for notifications in the specified registry key.
        ///
        /// Each part of the key must be provided separately so that the watcher
        /// can open its own handle.
        /// </summary>
        /// <param name="hive">The hive to watch</param>
        /// <param name="view">The view to watch</param>
        /// <param name="key">The key to watch</param>
        /// <param name="handler">The event handler to invoke</param>
        /// <param name="recursive">True to watch all subkeys as well</param>
        /// <param name="notifyValueChange">
        /// True to notify if a value is added, removed or updated.
        /// </param>
        /// <param name="notifyKeyChange">
        /// True to notify if a subkey is added or removed.
        /// </param>
        /// <param name="tag">
        /// An arbitrary identifier to include with any raised events.
        /// </param>
        /// <returns>
        /// An opaque token that can be pased to Remove, or null if the watcher
        /// could not be added.
        /// </returns>
        public object TryAdd(
            RegistryHive hive,
            RegistryView view,
            string key,
            RegistryChangedEventHandler handler,
            bool recursive         = false,
            bool notifyValueChange = true,
            bool notifyKeyChange   = true,
            object tag             = null
            )
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }
            if (handler == null)
            {
                throw new ArgumentNullException("handler");
            }
            if (!(notifyValueChange | notifyKeyChange))
            {
                throw new InvalidOperationException("Must wait for at least one type of change");
            }

            var args = new RegistryChangedEventArgs(
                hive,
                view,
                key,
                recursive,
                notifyValueChange,
                notifyKeyChange,
                tag
                );

            int             currentWatcher = -1;
            RegistryWatcher watcher;
            bool            needNewThread;
            var             token = TryAddInternal(handler, args, out needNewThread);

            while (needNewThread)
            {
                if (_extraWatchers == null)
                {
                    _extraWatchers = new List <RegistryWatcher>();
                }
                currentWatcher += 1;
                if (currentWatcher >= _extraWatchers.Count)
                {
                    watcher = new RegistryWatcher();
                    _extraWatchers.Add(watcher);
                }
                else
                {
                    watcher = _extraWatchers[currentWatcher];
                }
                token = watcher.TryAddInternal(handler, args, out needNewThread);
            }
            return(token);
        }
示例#3
0
 public static WatchEntry TryCreate(RegistryChangedEventHandler callback, RegistryChangedEventArgs args) {
     RegistryKey key;
     using (var baseKey = RegistryKey.OpenBaseKey(args.Hive, args.View)) {
         key = baseKey.OpenSubKey(args.Key, RegistryKeyPermissionCheck.Default, RegistryRights.Notify);
     }
     if (key == null) {
         return null;
     }
     return new WatchEntry(key, callback, args);
 }
示例#4
0
 private WatchEntry(
     RegistryKey key,
     RegistryChangedEventHandler callback,
     RegistryChangedEventArgs args
 ) {
     _key = key;
     _eventHandle = new AutoResetEvent(false);
     _callback = callback;
     _args = args;
     Register();
 }
示例#5
0
 public WatchEntry(RegistryChangedEventHandler callback, RegistryChangedEventArgs args)
 {
     using (var baseKey = RegistryKey.OpenBaseKey(args.Hive, args.View)) {
         _key = baseKey.OpenSubKey(args.Key, RegistryKeyPermissionCheck.Default, RegistryRights.Notify);
     }
     if (_key == null)
     {
         throw new ArgumentException("Key does not exist");
     }
     _eventHandle = new AutoResetEvent(false);
     _callback    = callback;
     _args        = args;
     Register();
 }
示例#6
0
 /// <summary>
 /// Starts listening for notifications in the specified registry key.
 /// 
 /// Each part of the key must be provided separately so that the watcher
 /// can open its own handle.
 /// </summary>
 /// <param name="hive">The hive to watch</param>
 /// <param name="view">The view to watch</param>
 /// <param name="key">The key to watch</param>
 /// <param name="handler">The event handler to invoke</param>
 /// <param name="recursive">True to watch all subkeys as well</param>
 /// <param name="notifyValueChange">
 /// True to notify if a value is added, removed or updated.
 /// </param>
 /// <param name="notifyKeyChange">
 /// True to notify if a subkey is added or removed.
 /// </param>
 /// <param name="tag">
 /// An arbitrary identifier to include with any raised events.
 /// </param>
 /// <exception cref="ArgumentException">
 /// The specified registry key does not exist.
 /// </exception>
 /// <returns>An opaque token that can be pased to Remove.</returns>
 /// <remarks>
 /// This is a thin layer over <see cref="TryAdd"/> that will throw an
 /// exception when the return value would be null.
 /// </remarks>
 public object Add(
     RegistryHive hive,
     RegistryView view,
     string key,
     RegistryChangedEventHandler handler,
     bool recursive = false,
     bool notifyValueChange = true,
     bool notifyKeyChange = true,
     object tag = null
 ) {
     var res = TryAdd(hive, view, key, handler, recursive, notifyValueChange, notifyKeyChange, tag);
     if (res == null) {
         throw new ArgumentException("Key does not exist");
     }
     return res;
 }
示例#7
0
        private object AddInternal(RegistryChangedEventHandler handler, RegistryChangedEventArgs args)
        {
            WatchEntry newEntry;

            lock (_eventsLock) {
                if (_entries.Count >= NativeMethods.MAXIMUM_WAIT_OBJECTS)
                {
                    return(null);
                }
                newEntry = new WatchEntry(handler, args);
                _entries.Add(newEntry);
            }

            _itemAdded.Set();

            return(newEntry);
        }
示例#8
0
        private object TryAddInternal(
            RegistryChangedEventHandler handler,
            RegistryChangedEventArgs args,
            out bool needNewThread
        ) {
            WatchEntry newEntry;
            needNewThread = false;

            lock (_eventsLock) {
                if (_entries.Count >= MAXIMUM_WAIT_OBJECTS) {
                    needNewThread = true;
                    return null;
                }
                newEntry = WatchEntry.TryCreate(handler, args);
                if (newEntry == null) {
                    return null;
                }
                _entries.Add(newEntry);
            }

            _itemAdded.Set();

            return newEntry;
        }
示例#9
0
        /// <summary>
        /// Starts listening for notifications in the specified registry key.
        /// 
        /// Each part of the key must be provided separately so that the watcher
        /// can open its own handle.
        /// </summary>
        /// <param name="hive">The hive to watch</param>
        /// <param name="view">The view to watch</param>
        /// <param name="key">The key to watch</param>
        /// <param name="handler">The event handler to invoke</param>
        /// <param name="recursive">True to watch all subkeys as well</param>
        /// <param name="notifyValueChange">
        /// True to notify if a value is added, removed or updated.
        /// </param>
        /// <param name="notifyKeyChange">
        /// True to notify if a subkey is added or removed.
        /// </param>
        /// <param name="tag">
        /// An arbitrary identifier to include with any raised events.
        /// </param>
        /// <returns>
        /// An opaque token that can be pased to Remove, or null if the watcher
        /// could not be added.
        /// </returns>
        public object TryAdd(
            RegistryHive hive,
            RegistryView view,
            string key,
            RegistryChangedEventHandler handler,
            bool recursive = false,
            bool notifyValueChange = true,
            bool notifyKeyChange = true,
            object tag = null
        ) {
            if (key == null) {
                throw new ArgumentNullException("key");
            }
            if (handler == null) {
                throw new ArgumentNullException("handler");
            }
            if (!(notifyValueChange | notifyKeyChange)) {
                throw new InvalidOperationException("Must wait for at least one type of change");
            }

            var args = new RegistryChangedEventArgs(
                hive,
                view,
                key,
                recursive,
                notifyValueChange,
                notifyKeyChange,
                tag
            );

            int currentWatcher = -1;
            RegistryWatcher watcher;
            bool needNewThread;
            var token = TryAddInternal(handler, args, out needNewThread);
            while (needNewThread) {
                if (_extraWatchers == null) {
                    _extraWatchers = new List<RegistryWatcher>();
                }
                currentWatcher += 1;
                if (currentWatcher >= _extraWatchers.Count) {
                    watcher = new RegistryWatcher();
                    _extraWatchers.Add(watcher);
                } else {
                    watcher = _extraWatchers[currentWatcher];
                }
                token = watcher.TryAddInternal(handler, args, out needNewThread);
            }
            return token;
        }
示例#10
0
 public WatchEntry(RegistryChangedEventHandler callback, RegistryChangedEventArgs args) {
     using (var baseKey = RegistryKey.OpenBaseKey(args.Hive, args.View)) {
         _key = baseKey.OpenSubKey(args.Key, RegistryKeyPermissionCheck.Default, RegistryRights.Notify);
     }
     if (_key == null) {
         throw new ArgumentException("Key does not exist");
     }
     _eventHandle = new AutoResetEvent(false);
     _callback = callback;
     _args = args;
     Register();
 }
示例#11
0
        private object AddInternal(RegistryChangedEventHandler handler, RegistryChangedEventArgs args) {
            WatchEntry newEntry;

            lock (_eventsLock) {
                if (_entries.Count >= NativeMethods.MAXIMUM_WAIT_OBJECTS) {
                    return null;
                }
                newEntry = new WatchEntry(handler, args);
                _entries.Add(newEntry);
            }

            _itemAdded.Set();

            return newEntry;
        }