Пример #1
0
        private async Task TestInput()
        {
            // Start a process to test against
            using (var process = Process.Start("notepad.exe"))
            {
                // 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, "TestInput");

                // Find the belonging window
                var notepadWindow = await WindowsEnumerator.EnumerateWindowsAsync()
                                    .Where(interopWindow =>
                {
                    User32Api.GetWindowThreadProcessId(interopWindow.Handle, out var processId);
                    return(processId == process.Id);
                })
                                    .FirstOrDefaultAsync();

                Assert.NotNull(notepadWindow);

                // Send input
                var sentInputs = KeyboardInputGenerator.KeyPresses(VirtualKeyCode.KeyR, VirtualKeyCode.KeyO, VirtualKeyCode.KeyB, VirtualKeyCode.KeyI, VirtualKeyCode.KeyN);
                // Test if we indead sent 10 inputs (5 x down & up)
                Assert.Equal((uint)10, sentInputs);

                // Kill the process
                process.Kill();
            }
        }
        /// <summary>
        ///     Get the process which the specified window belongs to, the value is cached into the ProcessId of the WindowInfo
        /// </summary>
        /// <param name="interopWindow">InteropWindow</param>
        /// <param name="forceUpdate">set to true to make sure the value is updated</param>
        /// <returns>int with process Id</returns>
        public static int GetProcessId(this IInteropWindow interopWindow, bool forceUpdate = false)
        {
            if (interopWindow.ProcessId.HasValue && !forceUpdate)
            {
                return(interopWindow.ProcessId.Value);
            }
            int processId;

            User32Api.GetWindowThreadProcessId(interopWindow.Handle, out processId);
            interopWindow.ProcessId = processId;
            return(interopWindow.ProcessId.Value);
        }
Пример #3
0
        /// <summary>
        ///     Set the window as foreground window
        /// </summary>
        /// <param name="interopWindow">The window to bring to the foreground</param>
        public static async ValueTask ToForegroundAsync(this IInteropWindow interopWindow)
        {
            // Nothing we can do if it's not visible!
            if (!interopWindow.IsVisible())
            {
                return;
            }

            var foregroundWindow = User32Api.GetForegroundWindow();

            // Window is already the foreground window
            if (foregroundWindow == interopWindow.Handle)
            {
                return;
            }
            if (interopWindow.IsMinimized())
            {
                interopWindow.Restore();
                while (interopWindow.IsMinimized())
                {
                    await Task.Delay(50).ConfigureAwait(false);
                }
            }

            // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms633539(v=vs.85).aspx
            // It was advised to use the menu (ALT) key, but this was a solution which Jan Karger showed me

            var threadId1 = User32Api.GetWindowThreadProcessId(foregroundWindow, IntPtr.Zero);
            var threadId2 = User32Api.GetWindowThreadProcessId(interopWindow.Handle, IntPtr.Zero);

            // Show window in foreground.
            if (threadId1 != threadId2)
            {
                User32Api.AttachThreadInput(threadId1, threadId2, 1);
                User32Api.SetForegroundWindow(interopWindow.Handle);
                User32Api.AttachThreadInput(threadId1, threadId2, 0);
            }
            else
            {
                User32Api.SetForegroundWindow(interopWindow.Handle);
            }

            // Show window in foreground.
            User32Api.BringWindowToTop(interopWindow.Handle);
            User32Api.SetForegroundWindow(interopWindow.Handle);
        }
Пример #4
0
        /// <summary>
        ///     Get the current "ClipboardOwner" but only if it isn't us!
        /// </summary>
        /// <returns>current clipboard owner</returns>
        private static string GetClipboardOwner()
        {
            string owner = null;

            try
            {
                var hWnd = ClipboardNative.CurrentOwner;
                if (hWnd != IntPtr.Zero)
                {
                    try
                    {
                        User32Api.GetWindowThreadProcessId(hWnd, out var pid);
                        using (var me = Process.GetCurrentProcess())
                            using (var ownerProcess = Process.GetProcessById(pid))
                            {
                                // Exclude myself
                                if (me.Id != ownerProcess.Id)
                                {
                                    // Get Process Name
                                    owner = ownerProcess.ProcessName;
                                    // Try to get the starting Process Filename, this might fail.
                                    try
                                    {
                                        owner = ownerProcess.Modules[0].FileName;
                                    }
                                    catch (Exception)
                                    {
                                        // Ignore
                                    }
                                }
                            }
                    }
                    catch (Exception e)
                    {
                        Log.Warn().WriteLine(e, "Non critical error: Couldn't get clipboard process, trying to use the title.");
                        owner = User32Api.GetText(hWnd);
                    }
                }
            }
            catch (Exception e)
            {
                Log.Warn().WriteLine(e, "Non critical error: Couldn't get clipboard owner.");
            }
            return(owner);
        }
Пример #5
0
        /// <summary>
        /// Get the path for the real modern app process belonging to the window
        /// </summary>
        /// <param name="interopWindow">IInteropWindow</param>
        /// <returns></returns>
        private static string GetAppProcessPath(IInteropWindow interopWindow)
        {
            int pid;

            User32Api.GetWindowThreadProcessId(interopWindow.Handle, out pid);
            if (string.Equals(interopWindow.GetClassname(), AppQuery.AppFrameWindowClass))
            {
                pid = interopWindow.GetChildren().FirstOrDefault(window => string.Equals(AppQuery.AppWindowClass, window.GetClassname()))?.GetProcessId() ?? 0;
            }
            if (pid <= 0)
            {
                return(null);
            }
            using (var process = Process.GetProcessById(pid))
            {
                return(process.MainModule.FileName);
            }
        }
Пример #6
0
        /// <summary>
        ///     Test scrolling a window
        /// </summary>
        /// <returns></returns>
        //[StaFact]
        private async Task TestScrollingAsync()
        {
            var breakScroll = false;

            IDisposable keyboardhook = null;

            try
            {
                keyboardhook = KeyboardHook.KeyboardEvents.Where(args => args.Key == VirtualKeyCode.Escape).Subscribe(args => breakScroll = true);
                // Start a process to test against
                using (var process = Process.Start("notepad.exe", "C:\\Windows\\setupact.log"))
                {
                    // Make sure it's started
                    Assert.NotNull(process);
                    // Wait until the process started it's message pump (listening for input)
                    process.WaitForInputIdle();

                    try
                    {
                        // Find the belonging window, by the process id
                        var notepadWindow = WindowsEnumerator.EnumerateWindows()
                                            .FirstOrDefault(interopWindow =>
                        {
                            User32Api.GetWindowThreadProcessId(interopWindow.Handle, out var processId);
                            return(processId == process.Id);
                        });
                        Assert.NotNull(notepadWindow);

                        // Create a WindowScroller
                        var scroller = notepadWindow.GetChildren().Select(window => window.GetWindowScroller()).FirstOrDefault();

                        Assert.NotNull(scroller);
                        // Notepad should have ScrollBarInfo
                        scroller.GetScrollbarInfo();
                        Assert.True(scroller.ScrollBar.HasValue);

                        Log.Info().WriteLine("Scrollbar info: {0}", scroller.ScrollBar.Value);

                        User32Api.SetForegroundWindow(scroller.ScrollingWindow.Handle);
                        await Task.Delay(1000);

                        // Just make sure the window is changed
                        KeyboardInputGenerator.KeyPresses(VirtualKeyCode.Next, VirtualKeyCode.Down);
                        await Task.Delay(2000);

                        scroller.ScrollMode  = ScrollModes.WindowsMessage;
                        scroller.ShowChanges = false;
                        // Move the window to the start
                        Assert.True(scroller.Start());
                        // A delay to make the window move
                        await Task.Delay(2000);

                        // Check if it did move to the start
                        Assert.True(scroller.IsAtStart);

                        // Loop
                        do
                        {
                            if (breakScroll)
                            {
                                break;
                            }
                            // Next "page"
                            Assert.True(scroller.Next());
                            // Wait a bit, so the window can update
                            await Task.Delay(300);

                            // Loop as long as we are not at the end yet
                        } while (!scroller.IsAtEnd);
                        scroller.Reset();
                    }
                    finally
                    {
                        // Kill the process
                        process.Kill();
                    }
                }
            }
            finally
            {
                keyboardhook?.Dispose();
            }
        }