Example #1
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);
 }
Example #2
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();
                }
            }
        }
Example #3
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));
        }