Example #1
0
 public static void FreeConsole()
 {
     if (!WinCon.FreeConsole())
     {
         throw new IOException("Unable to free console", Marshal.GetLastWin32Error());
     }
 }
Example #2
0
        private void ExitCmdProcess()
        {
            // Release attachment to the child process console.
            WinCon.FreeConsole();

            this.UIRoot = null;

            if (this.job != IntPtr.Zero)
            {
                WinBase.TerminateJobObject(this.job, 0);
            }
            this.job = IntPtr.Zero;
        }
Example #3
0
        private void ExitProcess()
        {
            Globals.SweepAllModules(this.context);

            // Release attachment to the child process console.
            WinCon.FreeConsole();

            this.UIRoot = null;

            if (this.job != IntPtr.Zero)
            {
                WinBase.TerminateJobObject(this.job, 0);
            }
            this.job = IntPtr.Zero;
        }
Example #4
0
        public void CheckClose()
        {
            string closeTestCmdLine = $"{closeTestBinaryLocation} -n {processCount} --log {testPipeName} --delay 1000 --no-realloc";

            using (var tokenSource = new CancellationTokenSource())
            {
                var token = tokenSource.Token;

                Task.Run(() => MakePipeServer(token), token);

                Log.Comment("Connect a test console window to the close test binary and wait for a few seconds.");
                CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext, closeTestCmdLine);
                Thread.Sleep(TimeSpan.FromSeconds(2));
                NativeMethods.Win32BoolHelper(WinCon.FreeConsole(), "Free console bindings so we aren't shut down when we kill the window.");
                Log.Comment("Click the close button on the window then wait a few seconds for it to cleanup.");
                app.GetCloseButton().Click();

                Thread.Sleep(TimeSpan.FromSeconds(5));
                tokenSource.Cancel();

                Log.Comment("Compare the output we received on our pipes to what we expected to get in terms of ordering and process count.");

                for (uint i = 1; i <= processCount; i++)
                {
                    string expected = string.Format(attachPattern, i);
                    Verify.AreEqual(expected, messages.Dequeue());
                }

                Verify.IsTrue(messages.Dequeue().StartsWith(spacerStartsWith));

                for (uint i = processCount; i >= 1; i--)
                {
                    string expected;
                    expected = string.Format(pausingPattern, i);
                    Verify.AreEqual(expected, messages.Dequeue());
                    expected = string.Format(exitingPattern, i);
                    Verify.AreEqual(expected, messages.Dequeue());
                }
            }
        }
Example #5
0
        private void CreateCmdProcess(string path, string link = "")
        {
            //string AdminPrefix = "Administrator: ";
            string WindowTitleToFind = "Host.Tests.UIA window under test";

            job = WinBase.CreateJobObject(IntPtr.Zero, IntPtr.Zero);
            NativeMethods.Win32NullHelper(job, "Creating job object to hold binaries under test.");

            Log.Comment("Attempting to launch command-line application at '{0}'", path);

            string binaryToRunPath = path;

#if __INSIDE_WINDOWS
            string launchArgs = binaryToRunPath;
#else
            string openConsolePath = Path.Combine(this.context.TestDeploymentDir, "OpenConsole.exe");

            string launchArgs = $"{openConsolePath}  {binaryToRunPath}";
#endif

            WinBase.STARTUPINFO si = new WinBase.STARTUPINFO();
            si.cb = Marshal.SizeOf(si);

            // If we were given a LNK file to startup with, set the STARTUPINFO structure to pass that information in to the console host.
            if (!string.IsNullOrEmpty(link))
            {
                si.dwFlags |= WinBase.STARTF.STARTF_TITLEISLINKNAME;
                si.lpTitle  = link;
            }

            WinBase.PROCESS_INFORMATION pi = new WinBase.PROCESS_INFORMATION();

            NativeMethods.Win32BoolHelper(WinBase.CreateProcess(null,
                                                                launchArgs,
                                                                IntPtr.Zero,
                                                                IntPtr.Zero,
                                                                false,
                                                                WinBase.CP_CreationFlags.CREATE_NEW_CONSOLE | WinBase.CP_CreationFlags.CREATE_SUSPENDED,
                                                                IntPtr.Zero,
                                                                null,
                                                                ref si,
                                                                out pi),
                                          "Attempting to create child host window process.");

            Log.Comment($"Host window PID: {pi.dwProcessId}");

            NativeMethods.Win32BoolHelper(WinBase.AssignProcessToJobObject(job, pi.hProcess), "Assigning new host window (suspended) to job object.");
            NativeMethods.Win32BoolHelper(-1 != WinBase.ResumeThread(pi.hThread), "Resume host window process now that it is attached and its launch of the child application will be caught in the job object.");

            Globals.WaitForTimeout();

            WinBase.JOBOBJECT_BASIC_PROCESS_ID_LIST list = new WinBase.JOBOBJECT_BASIC_PROCESS_ID_LIST();
            list.NumberOfAssignedProcesses = 2;

            int    listptrsize = Marshal.SizeOf(list);
            IntPtr listptr     = Marshal.AllocHGlobal(listptrsize);
            Marshal.StructureToPtr(list, listptr, false);

            TimeSpan totalWait    = TimeSpan.Zero;
            TimeSpan waitLimit    = TimeSpan.FromSeconds(30);
            TimeSpan pollInterval = TimeSpan.FromMilliseconds(500);
            while (totalWait < waitLimit)
            {
                WinBase.QueryInformationJobObject(job, WinBase.JOBOBJECTINFOCLASS.JobObjectBasicProcessIdList, listptr, listptrsize, IntPtr.Zero);
                list = (WinBase.JOBOBJECT_BASIC_PROCESS_ID_LIST)Marshal.PtrToStructure(listptr, typeof(WinBase.JOBOBJECT_BASIC_PROCESS_ID_LIST));

                if (list.NumberOfAssignedProcesses > 1)
                {
                    break;
                }
                else if (list.NumberOfAssignedProcesses < 1)
                {
                    Verify.Fail("Somehow we lost the one console host process in the job already.");
                }

                Thread.Sleep(pollInterval);
                totalWait += pollInterval;
            }
            Verify.IsLessThan(totalWait, waitLimit);

            WinBase.QueryInformationJobObject(job, WinBase.JOBOBJECTINFOCLASS.JobObjectBasicProcessIdList, listptr, listptrsize, IntPtr.Zero);
            list = (WinBase.JOBOBJECT_BASIC_PROCESS_ID_LIST)Marshal.PtrToStructure(listptr, typeof(WinBase.JOBOBJECT_BASIC_PROCESS_ID_LIST));

            Verify.AreEqual(list.NumberOfAssignedProcesses, list.NumberOfProcessIdsInList);

#if __INSIDE_WINDOWS
            pid = pi.dwProcessId;
#else
            // Take whichever PID isn't the host window's PID as the child.
            pid = pi.dwProcessId == (int)list.ProcessId ? (int)list.ProcessId2 : (int)list.ProcessId;
            Log.Comment($"Child command app PID: {pid}");
#endif

            // Free any attached consoles and attach to the console we just created.
            // The driver will bind our calls to the Console APIs into the child process.
            // This will allow us to use the APIs to get/set the console state of the test window.
            NativeMethods.Win32BoolHelper(WinCon.FreeConsole(), "Free existing console bindings.");
            // need to wait a bit or we might not be able to reliably attach
            System.Threading.Thread.Sleep(Globals.Timeout);
            NativeMethods.Win32BoolHelper(WinCon.AttachConsole((uint)pid), "Bind to the new PID for console APIs.");

            // we need to wait here for a bit or else
            // setting the console window title will fail.
            System.Threading.Thread.Sleep(Globals.Timeout * 5);
            NativeMethods.Win32BoolHelper(WinCon.SetConsoleTitle(WindowTitleToFind), "Set the window title so AppDriver can find it.");

            DesiredCapabilities appCapabilities = new DesiredCapabilities();
            appCapabilities.SetCapability("app", @"Root");
            Session = new IOSDriver <IOSElement>(new Uri(AppDriverUrl), appCapabilities);

            Verify.IsNotNull(Session);
            Actions = new Actions(Session);
            Verify.IsNotNull(Session);

            Globals.WaitForTimeout();

            // If we are running as admin, the child window title will have a prefix appended as it will also run as admin.
            //if (IsRunningAsAdmin())
            //{
            //    WindowTitleToFind = $"{AdminPrefix}{WindowTitleToFind}";
            //}

            Log.Comment($"Searching for window title '{WindowTitleToFind}'");
            this.UIRoot  = Session.FindElementByName(WindowTitleToFind);
            this.hStdOut = WinCon.GetStdHandle(WinCon.CONSOLE_STD_HANDLE.STD_OUTPUT_HANDLE);
            Verify.IsNotNull(this.hStdOut, "Ensure output handle is valid.");
            this.hStdErr = WinCon.GetStdHandle(WinCon.CONSOLE_STD_HANDLE.STD_ERROR_HANDLE);
            Verify.IsNotNull(this.hStdErr, "Ensure error handle is valid.");

            // Set the timeout to 15 seconds after we found the initial window.
            Session.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(15);
        }