Пример #1
0
        public Handler(StreamWriter BarInput, StreamReader BarOutput)
        {
            HwndBlackList  = new List <IntPtr>();
            workspaces     = new Dictionary <string, Workspace>();
            handledWindows = new List <IntPtr>();
            shellHookHelp  = new shellHookHelper(this);
            Running        = true;
            screens        = new List <Screen>(Screen.AllScreens);
            sortScreenList(ref screens);
            openedWorkspace = "0";

            RECT surface = screens[0].Bounds;
            //TODO: read from config
            int barHeight = 17;

            surface.Top = surface.Top + barHeight;
            workspaces.Add(openedWorkspace, new Workspace(this, surface));

            Configuration = new Config.Configuration();

            barInput  = BarInput;
            barOutput = BarOutput;

            /*
             * JsonStructures.Workspace[] testws = new JsonStructures.Workspace[1];
             * testws[0] = new JsonStructures.Workspace("lol");
             * Workspaces test = new Workspaces(testws,1);
             */

            titles = new Dictionary <IntPtr, string>();

            winHook         = new WinEventHook(WinEvents.EVENT_SYSTEM_FOREGROUND, WinEvents.EVENT_OBJECT_NAMECHANGE);
            winHook.Handle += eventReceiver;
        }
        public AmdDynamicVibranceProxy(IAmdAdapter amdAdapter, List <ApplicationSetting> applicationSettings, ResolutionModeWrapper windowsResolutionSettings)
        {
            _amdAdapter                = amdAdapter;
            _applicationSettings       = applicationSettings;
            _windowsResolutionSettings = windowsResolutionSettings;

            try
            {
                _vibranceInfo = new VibranceInfo();
                if (amdAdapter.IsAvailable())
                {
                    _vibranceInfo.isInitialized = true;
                    amdAdapter.Init();
                }

                if (_vibranceInfo.isInitialized)
                {
                    _hook = WinEventHook.GetInstance();
                    _hook.WinEventHookHandler += OnWinEventHook;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                MessageBox.Show(NvidiaDynamicVibranceProxy.NvapiErrorInitFailed, "vibranceGUI Error",
                                MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
Пример #3
0
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            // create a clock window for each secondary taskbar
            taskbars = TaskbarUtils.ListTaskbars().Where(x => !x.IsPrimary).ToList();

            if (taskbars.Count > 0)
            {
                // add a clock to each secondary taskbar
                var viewModel = new ViewModels.ClockViewModel();
                foreach (var taskbar in taskbars)
                {
                    var f = new ClockWindow(taskbar, viewModel);
                    f.Show();
                }

                // install a win event hook to track taskbar resize/movement
                var hook = WinEventHook.SetHook(WinEventHook.EVENT_OBJECT_LOCATIONCHANGE, WinEventProc);

                Application.ApplicationExit += (s, e) =>
                {
                    WinEventHook.RemoveHook(hook);
                };

                Application.Run();
            }
            else
            {
                MessageBox.Show("SecondaryTaskbarClock", "No secondary taskbars found. Application will terminate.");
            }
        }
Пример #4
0
        protected void EnableAttactWindow()
        {
            if (_windowEventHook != IntPtr.Zero)
            {
                return;
            }

            try
            {
                WinEventHook.WinEventDelegate windowEventDelegate = new WinEventHook.WinEventDelegate(AttachWindowEventCallback);
                _windowEventGCHandle = GCHandle.Alloc(windowEventDelegate);
                _windowEventHook     = WinEventHook.WinEventHookOne(WinEventHook.SWEH_Events.EVENT_OBJECT_LOCATIONCHANGE,
                                                                    windowEventDelegate,
                                                                    (uint)_gameMemory.Process.Id,
                                                                    WinEventHook.GetWindowThread(_gameMemory.Process.WindowHandle));
            }
            catch (Exception ex)
            {
                Plugin.ShowExceptionMessage(ex);
            }

            if (_windowEventHook == IntPtr.Zero)
            {
                DisableAttactWindow();
            }
        }
Пример #5
0
 public static IDisposable Subscribe(this IObserver <WinEventInfo> observer, WinEvents winEventStart, WinEvents winEventEnd, ObjectIdentifiers objectIdentifiers)
 {
     return(WinEventHook
            .Create(winEventStart, winEventEnd)
            .Where(x => x.IdChild == CHILDID_SELF && x.ObjectIdentifier == objectIdentifiers)
            .Subscribe(observer));
 }
Пример #6
0
        public AmdDynamicVibranceProxy(IAmdAdapter amdAdapter, List <ApplicationSetting> applicationSettings, Dictionary <string, Tuple <ResolutionModeWrapper, List <ResolutionModeWrapper> > > windowsResolutionSettings)
        {
            _amdAdapter                = amdAdapter;
            _applicationSettings       = applicationSettings;
            _windowsResolutionSettings = windowsResolutionSettings;

            try
            {
                _vibranceInfo = new VibranceInfo();
                if (amdAdapter.IsAvailable())
                {
                    _vibranceInfo.isInitialized = true;
                    amdAdapter.Init();
                }

                if (_vibranceInfo.isInitialized)
                {
                    _hook = WinEventHook.GetInstance();
                    _hook.WinEventHookHandler += OnWinEventHook;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                DialogResult result = MessageBox.Show(NvidiaDynamicVibranceProxy.NvapiErrorInitFailed, "vibranceGUI Error",
                                                      MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
                if (result == DialogResult.OK)
                {
                    Process.Start(NvidiaDynamicVibranceProxy.GuideLink);
                }
            }
        }
        public DefaultTaskbarWindowService(IAppSettings settings)
        {
            _hookInstance = this;

            Settings        = settings;
            ActivePlacement = settings.Placement;

            // install a win event hook to track taskbar resize/movement
            hookDelegate = new WinEventHook.WinEventDelegate(WinEventProc);
            var winHook = WinEventHook.SetHook(WinEventHook.EVENT_OBJECT_LOCATIONCHANGE, hookDelegate);

            Application.ApplicationExit += (s, e) =>
            {
                if (winHook != IntPtr.Zero)
                {
                    WinEventHook.RemoveHook(winHook);
                    winHook = IntPtr.Zero;

                    foreach (var f in GetWindows())
                    {
                        f.Close();
                        f.RestoreTaskbar();
                    }
                }
            };
        }
        public NvidiaDynamicVibranceProxy(List <ApplicationSetting> savedApplicationSettings, ResolutionModeWrapper currentWindowsResolutionSettings)
        {
            try
            {
                _applicationSettings       = savedApplicationSettings;
                _windowsResolutionSettings = currentWindowsResolutionSettings;
                _vibranceInfo = new VibranceInfo();
                if (initializeLibrary())
                {
                    InitializeProxy();
                }

                if (_vibranceInfo.isInitialized)
                {
                    _hook = WinEventHook.GetInstance();
                    _hook.WinEventHookHandler += OnWinEventHook;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                DialogResult result = MessageBox.Show(NvidiaDynamicVibranceProxy.NvapiErrorInitFailed, "vibranceGUI Error",
                                                      MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
                if (result == DialogResult.OK)
                {
                    Process.Start(GuideLink);
                }
            }
        }
Пример #9
0
        private void HookSpotify()
        {
            try
            {
                _spotify = Process.GetProcessesByName("spotify")[0];
            }
            catch (IndexOutOfRangeException)
            {
                // spotify isn't running; hook ObjectCreate and wait for it to launch
                _objectCreateHook = new WinEventHook(OnObjectCreate, WinEventHook.EventConstant.EVENT_OBJECT_CREATE);
                return;
            }

            // in case Mutify has been launched while Spotify is playing something
            if (_currentTitle != null)
            {
                VolumeControl.SetApplicationMute(_spotify.Id, _blacklist.Contains(_currentTitle));
                MuteAdButton.IsEnabled = true;
            }

            _spotify.EnableRaisingEvents = true; // register a handler
            _spotify.Exited += SpotifyExited;    // for spotify's exit

            // hook changes to Spotify's main window title so titles can be checked against the blacklist
            _windowNameHook = new WinEventHook(OnWindowNameChange, WinEventHook.EventConstant.EVENT_OBJECT_NAMECHANGE, _spotify.Id);
        }
Пример #10
0
 public void UnhookWinEvents()
 {
     foreach(var hook in hWinEventHooks)
     {
         WinEventHook.WinEventUnhook(hook);
     }
     hWinEventHooks.Clear();
 }
Пример #11
0
 private void UnhookSpotify()
 {
     if (_windowNameHook != null)
     {
         _windowNameHook.Stop();
         _windowNameHook = null;
     }
 }
Пример #12
0
 public void Startup()
 {
     // Subscribe the windows events which tell us a title was changed
     _winEventObservable = WinEventHook.WindowTileChangeObservable()
                           .Select(info => User32Api.GetText(info.Handle))
                           .Where(title => !string.IsNullOrEmpty(title))
                           .Subscribe(MonitorTitleChangeEvent);
 }
Пример #13
0
 public void ShowMessages()
 {
     using (var wih = new WinEventHook())
     {
         wih.ForegroundWindowChanged.Subscribe(_ => Console.WriteLine(_));
         Thread.Sleep(TimeSpan.FromSeconds(60));
     }
 }
Пример #14
0
        private bool CreateOverlay()
        {
            if (_isOverlayInitialized && !_isOverlayReady && _gameMemory.Process.WindowHandle != IntPtr.Zero)
            {
                _window.Create();

                _graphics.Width        = _window.Width;
                _graphics.Height       = _window.Height;
                _graphics.WindowHandle = _window.Handle;
                _graphics.Setup();

                _window.SizeChanged += (object sender, OverlaySizeEventArgs e) =>
                                       _graphics.Resize(_window.Width, _window.Height);

                _window.FitTo(_gameMemory.Process.WindowHandle, true);

                if (_windowEventDispatcher != null)
                {
                    _windowEventDispatcher.Invoke(delegate
                    {
                        WinEventHook.WinEventDelegate windowEventDelegate = new WinEventHook.WinEventDelegate(MoveGameWindowEventCallback);
                        _windowEventGCHandle = GCHandle.Alloc(windowEventDelegate);
                        _windowEventHook     = WinEventHook.WinEventHookOne(WinEventHook.SWEH_Events.EVENT_OBJECT_LOCATIONCHANGE,
                                                                            windowEventDelegate,
                                                                            (uint)_gameMemory.Process.Id,
                                                                            WinEventHook.GetWindowThread(_gameMemory.Process.WindowHandle));
                    });
                }

                //Get a refernence to the underlying RenderTarget from SharpDX. This'll be used to draw portions of images.
                _device = (SharpDX.Direct2D1.WindowRenderTarget) typeof(Graphics)
                          .GetField("_device", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
                          .GetValue(_graphics);

                _consolas14Bold = _graphics.CreateFont("Consolas", 14, true);
                _consolas16Bold = _graphics.CreateFont("Consolas", 16, true);
                _consolas32Bold = _graphics.CreateFont("Consolas", 32, true);

                _black      = _graphics.CreateSolidBrush(0, 0, 0, Config.Opacity);
                _white      = _graphics.CreateSolidBrush(255, 255, 255, Config.Opacity);
                _green      = _graphics.CreateSolidBrush(0, 128, 0, Config.Opacity);
                _lawngreen  = _graphics.CreateSolidBrush(124, 252, 0, Config.Opacity);
                _red        = _graphics.CreateSolidBrush(255, 0, 0, Config.Opacity);
                _darkred    = _graphics.CreateSolidBrush(139, 0, 0, Config.Opacity);
                _grey       = _graphics.CreateSolidBrush(128, 128, 128, Config.Opacity);
                _darkergrey = _graphics.CreateSolidBrush(60, 60, 60, Config.Opacity);
                _gold       = _graphics.CreateSolidBrush(255, 215, 0, Config.Opacity);
                _goldenrod  = _graphics.CreateSolidBrush(218, 165, 32, Config.Opacity);
                _violet     = _graphics.CreateSolidBrush(238, 130, 238, Config.Opacity);

                _characterSheet = ImageLoader.LoadBitmap(_device, Properties.Resources.portraits);
                _inventorySheet = ImageLoader.LoadBitmap(_device, Properties.Resources.objects);

                _isOverlayReady = true;
            }

            return(_isOverlayReady);
        }
Пример #15
0
        public override int Shutdown()
        {
            SaveConfiguration(Config);

            try
            {
                if (_windowEventGCHandle.IsAllocated)
                {
                    _windowEventGCHandle.Free();
                }

                if (_windowEventHook != IntPtr.Zero)
                {
                    WinEventHook.WinEventUnhook(_windowEventHook);
                }

                _windowEventDispatcher?.InvokeShutdown();
            }
            catch (Exception ex)
            {
                _hostDelegates.ExceptionMessage(ex);
            }

            _black?.Dispose();
            _white?.Dispose();
            _green?.Dispose();
            _lawngreen?.Dispose();
            _grey?.Dispose();
            _darkergrey?.Dispose();
            _red?.Dispose();
            _darkred?.Dispose();
            _gold?.Dispose();
            _goldenrod?.Dispose();
            _violet?.Dispose();

            _consolas14Bold?.Dispose();
            _consolas16Bold?.Dispose();
            _consolas32Bold?.Dispose();

            _characterSheet?.Dispose();
            _characterToImageTranslation = null;

            _windowEventHook       = IntPtr.Zero;
            _windowEventDispatcher = null;

            _device = null;
            _graphics?.Dispose();
            _graphics = null;
            _window?.Dispose();
            _window = null;

            _isOverlayInitialized = false;
            _isOverlayReady       = false;

            return(0);
        }
Пример #16
0
        protected void UpdateAttachWindowOffset()
        {
            if (_gameMemory.Process.WindowHandle == IntPtr.Zero)
            {
                return;
            }

            Utilities.Rect rect = WinEventHook.GetWindowRect(_gameMemory.Process.WindowHandle);

            Properties.Settings.Default.YOffset = (int)(rect.Top - Top);
            Properties.Settings.Default.XOffset = (int)(rect.Left - Left);
        }
Пример #17
0
        /// <summary>
        /// The constructor
        /// </summary>
        /// <param name="pipConfiguration">IPipConfiguration</param>
        /// <param name="locationPool">LocationPool used to find a location</param>
        /// <param name="hWnd">IntPtr with the hWnd to mirror</param>
        /// <param name="uiSynchronizationContext">SynchronizationContext used to make it possible to modify the UI</param>
        public ThumbnailForm(IPipConfiguration pipConfiguration, LocationPool locationPool, IntPtr hWnd, SynchronizationContext uiSynchronizationContext)
        {
            _thumbnailRect = locationPool.Pool();
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            _pipConfiguration = pipConfiguration;
            _locationPool     = locationPool;

            // Make sure that changes to the settings are applied
            _configurationMonitor = _pipConfiguration.OnPropertyChanged()
                                    .Where(args => PropertiesToMonitor.Contains(args.PropertyName))
                                    .Throttle(TimeSpan.FromMilliseconds(200))
                                    .SubscribeOn(uiSynchronizationContext)
                                    .ObserveOn(uiSynchronizationContext)
                                    .Subscribe(args => UpdateThumbnail());

            _hWnd = hWnd;

            // Make sure the PIP closes when the source closes
            _windowCloseMonitor = WinEventHook.Create(WinEvents.EVENT_OBJECT_DESTROY)
                                  .SubscribeOn(uiSynchronizationContext)
                                  .ObserveOn(uiSynchronizationContext)
                                  .Subscribe(info =>
            {
                if (info.Handle == _hWnd)
                {
                    Close();
                }
            });

            // Make sure the thumbnail changes when the window changes
            _windowSizeChangeMonitor = WinEventHook.Create(WinEvents.EVENT_OBJECT_LOCATIONCHANGE)
                                       .SubscribeOn(uiSynchronizationContext)
                                       .ObserveOn(uiSynchronizationContext)
                                       .Subscribe(info =>
            {
                if (info.Handle == _hWnd)
                {
                    UpdateThumbnail();
                }
            });

            Location        = _thumbnailRect.Location;
            Size            = _thumbnailRect.Size;
            StartPosition   = FormStartPosition.Manual;
            TopMost         = true;
            Text            = "PIP";
            FormBorderStyle = FormBorderStyle.None;
            BackColor       = Color.Gray;
            Enabled         = false;
            ShowInTaskbar   = false;
        }
Пример #18
0
        private void PinForm_Load(object sender, EventArgs e)
        {
            if (this._parentHandle == IntPtr.Zero)
            {
                return;
            }

            this._winEventHook = new WinEventHook(this._parentHandle);
            this._winEventHook.Add(EventId.EVENT_OBJECT_LOCATIONCHANGE, ParentForm_Moved);
            this._winEventHook.Add(EventId.EVENT_SYSTEM_MOVESIZEEND, ParentForm_Moved);
            this._winEventHook.Add(EventId.EVENT_OBJECT_DESTROY, ParentForm_Destroyed);

            this.MoveToParentWindow();
        }
Пример #19
0
        protected void UpdateAttachWindowPosition()
        {
            if (_gameMemory.Process.WindowHandle == IntPtr.Zero)
            {
                return;
            }

            Utilities.Rect rect = WinEventHook.GetWindowRect(_gameMemory.Process.WindowHandle);

            _isAttachWindowUpdate = true;
            Top  = rect.Top - Properties.Settings.Default.YOffset;
            Left = rect.Left - Properties.Settings.Default.XOffset;
            _isAttachWindowUpdate = false;
        }
Пример #20
0
        private void OnObjectCreate(IntPtr hWinEventHook, uint eventType, IntPtr hWnd,
                                    int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
        {
            int pid;

            GetWindowThreadProcessId(hWnd, out pid); // return value is thread id i.e. not useful here

            if (Process.GetProcessById(pid).ProcessName == "spotify")
            {
                _objectCreateHook.Stop();
                _objectCreateHook = null;
                HookSpotify();
            }
        }
Пример #21
0
 /// <summary>
 /// </summary>
 /// <param name="parentHandle">Handle of window to inject</param>
 public InjectableForm(IntPtr parentHandle) : this()
 {
     winEventHook = new WinEventHook(ParentHandle);
     //SetParent(Handle, ParentHandle);
     ParentHandle = parentHandle;
     Load        += (sender, args) =>
     {
         winEventHook.Add(ApiWinEventHook.EventId.EventObjectLocationchange, ParentForm_Moved);
         winEventHook.Add(ApiWinEventHook.EventId.EventSystemMovesizeend, ParentForm_Moved);
         winEventHook.Add(ApiWinEventHook.EventId.EventObjectDestroy, ParentForm_Destroyed);
         winEventHook.Add(ApiWinEventHook.EventId.EventObjectHide, ParentForm_Hide);
         winEventHook.Add(ApiWinEventHook.EventId.EventObjectShow, ParentForm_Show);
         MoveToParentWindow();
     };
 }
Пример #22
0
        void _ThreadProc()
        {
            WindowsHook hk = null, hm = null; WinEventHook hwe = null;

            try {
                try {
                    if (_block.Has(BIEvents.Keys))
                    {
                        hk = WindowsHook.Keyboard(_keyHookProc ??= _KeyHookProc);
                    }
                    if (_block.HasAny(BIEvents.MouseClicks | BIEvents.MouseMoving))
                    {
                        hm = WindowsHook.Mouse(_mouseHookProc ??= _MouseHookProc);
                    }
                }
                catch (AuException e1) { Debug_.Print(e1); _block = 0; return; }                 //failed to hook

                //This prevents occassional inserting a foreign key after the first our-script-pressed key.
                //To reproduce, let our script send small series of chars in loop, and simultaneously a foreign script send other chars.
                wait.doEvents();

                //print.it("started");
                Api.SetEvent(_syncEvent);

                //the hook detects Ctrl+Alt+Del, Win+L, UAC consent, etc. SystemEvents.SessionSwitch only Win+L.
                try { hwe = new WinEventHook(EEvent.SYSTEM_DESKTOPSWITCH, 0, _winEventProc ??= _WinEventProc); }
                catch (AuException e1) { Debug_.Print(e1); }                 //failed to hook

                wait.Wait_(-1, WHFlags.DoEvents, _stopEvent, _threadHandle);

                if (_blockedKeys != null)
                {
                    bool onlyUp = _discardBlockedKeys || Environment.TickCount64 - _startTime > c_maxResendTime;
                    _blockedKeys.SendBlocked_(onlyUp);
                }
                //print.it("ended");
            }
            finally {
                _blockedKeys = null;
                hk?.Dispose();
                hm?.Dispose();
                hwe?.Dispose();
                Api.SetEvent(_syncEvent);
            }
            GC.KeepAlive(this);
        }
Пример #23
0
        AdminProcess()
        {
            _timer = new timer(_Timer);

            //use hook to detect when drag-drop started
            _hook = new WinEventHook(EEvent.SYSTEM_CAPTURESTART, 0, d => {
                _EndedDragMode();
                if (0 == d.w.ClassNameIs("CLIPBRDWNDCLASS", "DragWindow"))
                {
                    return;
                }
                _StartedDragMode();
            }, flags: EHookFlags.SKIPOWNPROCESS);

            //note: we don't use SYSTEM_CAPTUREEND. It's too early and sometimes missing.
            //tested: no EVENT_SYSTEM_DRAGDROPSTART events.
            //info: classname "DragWindow" is of Windows Store.
            //rejected: int pid = d.w.ProcessId; using(var u = uacInfo.ofProcess(pid)) { if(u == null || u.Elevation == UacElevation.Full) return; }
        }
Пример #24
0
        private async Task TestWinEventHook()
        {
            // This takes care of having a WinProc handler, to make sure the messages arrive
            var winProcHandler = WinProcHandler.Instance;
            // This buffers the observable
            var replaySubject = new ReplaySubject <IInteropWindow>();

            var winEventObservable = WinEventHook.WindowTileChangeObservable()
                                     .Select(info => InteropWindowFactory.CreateFor(info.Handle).Fill())
                                     .Where(interopWindow => !string.IsNullOrEmpty(interopWindow?.Caption))
                                     .Subscribe(interopWindow =>
            {
                Log.Debug().WriteLine("Window title change: Process ID {0} - Title: {1}", interopWindow.Handle, interopWindow.Caption);
                replaySubject.OnNext(interopWindow);
            }, exception => Log.Error().WriteLine("An error occured", exception));
            await Task.Delay(100);

            // Start a process to test against
            using (var process = Process.Start("notepad.exe"))
            {
                try
                {
                    // Make sure it's started
                    Assert.NotNull(process);
                    // Wait until the process started it's message pump (listening for input)
                    process.WaitForInputIdle();
                    User32Api.SetWindowText(process.MainWindowHandle, "TestWinEventHook - Test");

                    // Find the belonging window
                    var notepadWindow = await replaySubject.Where(info => info != null && info.ProcessId == process.Id).FirstAsync();

                    Assert.Equal(process.Id, notepadWindow?.ProcessId);
                }
                finally
                {
                    winEventObservable.Dispose();
                    process?.Kill();
                }
            }
        }
Пример #25
0
        protected void DisableAttactWindow()
        {
            try
            {
                if (_windowEventGCHandle.IsAllocated)
                {
                    _windowEventGCHandle.Free();
                }

                if (_windowEventHook != IntPtr.Zero)
                {
                    WinEventHook.WinEventUnhook(_windowEventHook);
                }
            }
            catch (Exception ex)
            {
                Plugin.ShowExceptionMessage(ex);
            }
            finally
            {
                _windowEventHook = IntPtr.Zero;
            }
        }
 public override void Start()
 {
     _eventHook              = new WinEventHook(WinEventHook.EVENT_OBJECT_NAMECHANGE, 0);
     _eventHook.OnHookEvent += OnHookEvent;
 }
Пример #27
0
        /// <summary>
        ///     The OAuth code receiver
        /// </summary>
        /// <param name="authorizeMode">which of the AuthorizeModes was used to call the method</param>
        /// <param name="codeReceiverSettings"></param>
        /// <param name="cancellationToken">CancellationToken</param>
        /// <returns>Dictionary with values</returns>
        public async Task <IDictionary <string, string> > ReceiveCodeAsync(AuthorizeModes authorizeMode, ICodeReceiverSettings codeReceiverSettings,
                                                                           CancellationToken cancellationToken = default)
        {
            // Force OOB Uri, if nothing is set
            if (string.IsNullOrEmpty(codeReceiverSettings.RedirectUrl))
            {
                switch (authorizeMode)
                {
                case AuthorizeModes.OutOfBound:
                    codeReceiverSettings.RedirectUrl = "urn:ietf:wg:oauth:2.0:oob";
                    break;

                case AuthorizeModes.OutOfBoundAuto:
                    codeReceiverSettings.RedirectUrl = "urn:ietf:wg:oauth:2.0:oob:auto";
                    break;

                default:
                    throw new NotSupportedException($"Only {AuthorizeModes.OutOfBound} and {AuthorizeModes.OutOfBoundAuto} are supported modes for this receiver");
                }
            }

            var uriBuilder = new UriBuilder(codeReceiverSettings.AuthorizationUri)
            {
                Query = codeReceiverSettings.AuthorizationUri.QueryToKeyValuePairs()
                        .Select(x => new KeyValuePair <string, string>(x.Key, x.Value.FormatWith(codeReceiverSettings)))
                        .ToQueryString()
            };

            // Get the formatted FormattedAuthUrl
            var authorizationUrl = uriBuilder.Uri;

            Log.Debug().WriteLine("Opening a browser with: {0}", authorizationUrl.AbsoluteUri);
            // Open the url in the default browser
            var processStartInfo = new ProcessStartInfo(authorizationUrl.AbsoluteUri)
            {
                CreateNoWindow  = true,
                UseShellExecute = true
            };

            Process.Start(processStartInfo);

            Log.Debug().WriteLine("Waiting until a window gets a title with the state {0}", codeReceiverSettings.State);
            // Wait until a window get's a title which contains the state object
            var title = await WinEventHook.WindowTileChangeObservable()
                        .Select(info => InteropWindowFactory.CreateFor(info.Handle).Fill())
                        .Where(interopWindow => !string.IsNullOrEmpty(interopWindow?.Caption))
                        .Where(interopWindow => interopWindow.Caption.Contains(codeReceiverSettings.State))
                        // Skip temporary titles, where the redirect URL os briefly seen
                        .Where(interopWindow => interopWindow?.Caption.Contains(codeReceiverSettings.RedirectUrl) != true)
                        .Select(interopWindow => interopWindow.Caption)
                        .Take(1).ToTask(cancellationToken);

            Log.Debug().WriteLine("Got title {0}", title);
            if (string.IsNullOrEmpty(title))
            {
                return(new Dictionary <string, string>());
            }

            var match = QueryPartOfTitleRegEx.Match(title);

            if (!match.Success)
            {
                return(UriParseExtensions.QueryStringToDictionary(title));
            }

            var queryParameters = match.Groups["query"]?.Value;

            if (string.IsNullOrEmpty(queryParameters))
            {
                return(new Dictionary <string, string>());
            }
            Log.Debug().WriteLine("Query parameters: {0}", queryParameters);
            // Return result of the listening
            return(UriParseExtensions.QueryStringToDictionary(queryParameters));
        }