예제 #1
0
파일: FlaxWindow.cs 프로젝트: teonsen/Flax
 internal void SetFlaUIWindow()
 {
     using (var automation = new FlaUI.UIA3.UIA3Automation())
     {
         var app = FlaUI.Core.Application.Attach(PID);
         _FlaUIWindow = app.GetMainWindow(automation);
         //UIElement = new UIElement(this, _FlaUIWindow);
     }
 }
예제 #2
0
 public static Window RequireTopLevelWindow(Application application, UIA3Automation automation,
                                            Func <Window, bool> filter, string timeoutMessage, int timeoutSeconds = 5)
 {
     return(Retry.WhileNull(() =>
                            // ReSharper disable once AccessToDisposedClosure
                            application.GetAllTopLevelWindows(automation).FirstOrDefault(filter),
                            throwOnTimeout: true, timeout: TimeSpan.FromSeconds(timeoutSeconds), timeoutMessage: timeoutMessage
                            ).Result);
 }
예제 #3
0
        /// <summary>
        /// Finds the main AASX Package Explorer window and executes the code dependent on it.
        /// </summary>
        /// <remarks>This method is necessary since splash screen confuses FlaUI and prevents us from
        /// easily determining the main window.</remarks>
        /// <param name="implementation">Code to be executed</param>
        public static void RunWithMainWindow(Implementation implementation)
        {
            string environmentVariable = "AASX_PACKAGE_EXPLORER_RELEASE_DIR";
            string releaseDir          = System.Environment.GetEnvironmentVariable(environmentVariable);

            if (releaseDir == null)
            {
                throw new InvalidOperationException(
                          $"Expected the environment variable to be set: {environmentVariable}; " +
                          "otherwise we can not find binaries to be tested through functional tests.");
            }

            string pathToExe = Path.Combine(releaseDir, "AasxPackageExplorer.exe");

            if (!File.Exists(pathToExe))
            {
                throw new FileNotFoundException(
                          "The executable of the AASX Package Explorer " +
                          $"could not be found in the release directory: {pathToExe}; did you compile it properly before?");
            }

            var app = Application.Launch(pathToExe);

            try
            {
                using (var automation = new UIA3Automation())
                {
                    // ReSharper disable once AccessToDisposedClosure
                    Retry.WhileEmpty(() => app.GetAllTopLevelWindows(automation));

                    var mainWindow = app
                                     .GetAllTopLevelWindows(automation)
                                     .First((w) => w.Title == "AASX Package Explorer");

                    implementation(app, automation, mainWindow);
                }
            }
            finally
            {
                app.Kill();
            }
        }
예제 #4
0
        internal static AutomationElement GetNativeElement(CodeActivityContext context,
                                                           InArgument <string> arg_WindowTitle,
                                                           InArgument <string> arg_AutomationId,
                                                           InArgument <string> arg_Name)
        {
            string title        = arg_WindowTitle.Get(context) ?? "";
            string automationId = arg_AutomationId.Get(context) ?? "";
            string name         = arg_Name.Get(context) ?? "";

            if (title.Length > 0 && (automationId.Length > 0 || name.Length > 0))
            {
                using (var automation = new FlaUI.UIA3.UIA3Automation())
                {
                    AutomationElement parentWindowAE = null;
                    uint lpdwProcessId;
                    var  hWnd = GetWindowHandleFromTitle(title);
                    FlaUI.Core.WindowsAPI.User32.GetWindowThreadProcessId(hWnd, out lpdwProcessId);
                    var app = FlaUI.Core.Application.Attach((int)lpdwProcessId);
                    parentWindowAE = app.GetMainWindow(automation);

                    // 1.Use AutomationId property to get the element.
                    if (automationId.Length > 0)
                    {
                        return(Retry.WhileNull(() =>
                                               parentWindowAE.FindFirstDescendant(cf => cf.ByAutomationId(automationId)), throwOnTimeout: false, ignoreException: true).Result);
                    }
                    // 2.Use Name property to get the element.
                    if (name.Length > 0)
                    {
                        return(Retry.WhileNull(() =>
                                               parentWindowAE.FindFirstDescendant(cf => cf.ByName(name)), throwOnTimeout: false, ignoreException: true).Result);
                    }
                }
            }
            return(null);
        }
예제 #5
0
 public static Window RequireTopLevelWindowByTitle(Application application, UIA3Automation automation,
                                                   string title, int timeoutSeconds = 5)
 {
     return(RequireTopLevelWindow(application, automation, (w) => w.Title == title,
                                  $"Could not find the top-level window with the title {Quote(title)}", timeoutSeconds));
 }
예제 #6
0
        /// <summary>
        /// Finds the main AASX Package Explorer window and executes the code dependent on it.
        /// </summary>
        /// <remarks>This method is necessary since splash screen confuses FlaUI and prevents us from
        /// easily determining the main window.</remarks>
        /// <param name="implementation">Code to be executed</param>
        /// <param name="run">Run options. If null, a new run with default values is used</param>
        public static void RunWithMainWindow(Implementation implementation, Run?run = null)
        {
            string releaseDir = ReleaseDir();
            string pathToExe  = Path.Combine(releaseDir, "AasxPackageExplorer.exe");

            if (!File.Exists(pathToExe))
            {
                throw new FileNotFoundException(
                          "The executable of the AASX Package Explorer " +
                          $"could not be found in the release directory: {pathToExe}; did you compile it properly before?");
            }

            var resolvedRun = run ?? new Run();

            // See https://stackoverflow.com/questions/5510343/escape-command-line-arguments-in-c-sharp
            string joinedArgs = string.Join(
                " ",
                resolvedRun.Args
                .Select(arg => Regex.Replace(arg, @"(\\*)" + "\"", @"$1$1\" + "\"")));

            var psi = new ProcessStartInfo
            {
                FileName              = pathToExe,
                Arguments             = joinedArgs,
                RedirectStandardError = true,
                WorkingDirectory      = releaseDir,
                UseShellExecute       = false
            };

            bool gotStderr = false;

            var process = new Process {
                StartInfo = psi
            };

            try
            {
                process.ErrorDataReceived += (sender, e) =>
                {
                    if (!string.IsNullOrEmpty(e.Data))
                    {
                        gotStderr = true;
                        TestContext.Error.WriteLine(e.Data);
                    }
                };

                process.Start();
                process.BeginErrorReadLine();
            }
            catch (Exception)
            {
                TestContext.Error.WriteLine(
                    $"Failed to launch the process: FileName: {psi.FileName}, " +
                    $"Arguments: {psi.Arguments}, Working directory: {psi.WorkingDirectory}");
                throw;
            }

            var app = new Application(process, false);

            try
            {
                using var automation = new UIA3Automation();

                var mainWindow = Retry.Find(() =>
                                            // ReSharper disable once AccessToDisposedClosure
                                            app.GetAllTopLevelWindows(automation)
                                            .FirstOrDefault(
                                                (w) => w.AutomationId == "mainWindow"),
                                            new RetrySettings
                {
                    ThrowOnTimeout = true,
                    Timeout        = TimeSpan.FromSeconds(5),
                    TimeoutMessage = "Could not find the main window"
                }).AsWindow();

                implementation(app, automation, mainWindow);
            }
            finally
            {
                if (!resolvedRun.DontKill)
                {
                    app.Kill();
                }
            }

            if (gotStderr)
            {
                throw new AssertionException(
                          "Unexpected writes to standard error. Please see the test context for more detail.");
            }
        }