/// <summary> /// Internal method to create the value changed observable /// </summary> /// <param name="key"></param> /// <param name="filter"></param> /// <returns></returns> private static IObservable <Unit> CreateKeyValuesChangedObservable(IntPtr key, RegistryNotifyFilter filter) { return(Observable.Create <Unit>( obs => { var eventNotify = new AutoResetEvent(false); var result = Advapi32Api.RegNotifyChangeKeyValue(key, true, filter, eventNotify.SafeWaitHandle.DangerousGetHandle(), true); if (result != 0) { obs.OnError(new Win32Exception(Marshal.GetLastWin32Error())); } return new CompositeDisposable( eventNotify, SetCallbackWhenSignalled(eventNotify, () => { obs.OnNext(Unit.Default); obs.OnCompleted(); })); }).Repeat()); }
/// <summary> /// Create an observable to monitor for registry changes /// </summary> /// <param name="hKey">IntPtr</param> /// <param name="subKey">string</param> /// <param name="registrationScheduler">IScheduler</param> /// <param name="filter">RegistryNotifyFilter</param> /// <returns>IObservable</returns> public static IObservable <Unit> ObserveChanges(IntPtr hKey, string subKey, IScheduler registrationScheduler = null, RegistryNotifyFilter filter = RegistryNotifyFilter.ChangeLastSet) { return(Observable.Create <Unit>( obs => { try { var result = Advapi32Api.RegOpenKeyEx(hKey, subKey, RegistryOpenOptions.None, RegistryKeySecurityAccessRights.Read, out var registryKey); if (result != 0) { throw new Win32Exception(Marshal.GetLastWin32Error()); } return new CompositeDisposable( CreateKeyValuesChangedObservable(registryKey, filter).SubscribeOn(registrationScheduler ?? Scheduler.CurrentThread).Subscribe(obs), Disposable.Create(() => Advapi32Api.RegCloseKey(registryKey))); } catch (Win32Exception e) { obs.OnError(e); return Disposable.Empty; } })); }