/// <summary>
        /// AppMonitorLoader Main Method for STi consumption, direct-application-launching version
        /// </summary>
        /// <param name="commandline">Arguments to AppMonitor loader, either a config file or original format</param>
        public static void RunApplication(string commandline)
        {
            ProcessStartInfo pInfo = ProcessArgs(commandline);

            DictionaryStore.StartServer();

            ApplicationMonitor appMon = new ApplicationMonitor();

            // if we're launching a ClickOnce application, clean the cache
            // Since this method precludes remote deployment and our enlistment should build properly signed manifests, there's no need to update / resign the manifests.
            if (pInfo.FileName.ToLowerInvariant().EndsWith(ApplicationDeploymentHelper.STANDALONE_APPLICATION_EXTENSION) || pInfo.FileName.ToLowerInvariant().EndsWith(ApplicationDeploymentHelper.BROWSER_APPLICATION_EXTENSION))
            {
                ApplicationDeploymentHelper.CleanClickOnceCache();
            }
            // shell exec the app
            appMon.StartProcess(pInfo);

            // Some Xbap tests exit early unless we add PresentationHost.exe as a monitored process.  Has to happen after StartProcess.
            // Timing is not an issue, since this is simply adding a string to a List, so will execute orders of magnitude faster than actually starting any Xbap.
            if (pInfo.FileName.ToLowerInvariant().EndsWith(ApplicationDeploymentHelper.BROWSER_APPLICATION_EXTENSION))
            {
                appMon.MonitorProcess("PresentationHost.exe");
            }
            appMon.WaitForUIHandlerAbort();
            CloseCurrentVariationIfOneExists();
            appMon.Close();
        }
Exemple #2
0
        /// <summary>
        /// Start Host
        /// </summary>
        /// <param name="startupUri"></param>
        public void StartHost(string startupUri)
        {
            if (monitor != null)
            {
                throw new InvalidOperationException("You must first Close the Host before calling StartHost again.");
            }

            DictionaryStore.StartServer();
            //use a custom startup page
            if (!string.IsNullOrEmpty(startupUri))
            {
                DictionaryStore.Current[UiaDistributedTestcaseHost.StartupUriId] = startupUri;
            }

            monitor = new ApplicationMonitor();
            GetHwndUIHandler handler = new GetHwndUIHandler();

            // register for iexplore and have your app set the title
            monitor.RegisterUIHandler(handler, "iexplore", "RegExp:(Ready)", UIHandlerNotification.TitleChanged);

            //Clear the Click Once cache so the app is always re-activated
            ApplicationDeploymentHelper.CleanClickOnceCache();

            //run the app
            monitor.StartProcess(xbapFileName);

            //wait for the UIHandler to return abort or timeout in 90 seconds
            if (!monitor.WaitForUIHandlerAbort(90000) || handler.topLevelhWnd == IntPtr.Zero)
            {
                throw new TimeoutException("A timeout occured while waiting for the XamlBrowserHost to navigate to the startUpPage");
            }

            //

            monitor.StopMonitoring();

            //Get the remoteHost object
            //


            //if we timedout then let the caller know that the app is not hosting this object
            //if (remoteHost == null)
            //    throw new InvalidOperationException("The launched application did not create a host object in the Harness remote site");

            //set the host hwnd
            hWndHost = handler.topLevelhWnd;
        }
Exemple #3
0
        /// <summary>
        /// Performs the Activation step
        /// </summary>
        /// <returns>returns true if the rest of the steps should be executed, otherwise, false</returns>
        protected override bool BeginStep()
        {
            //Create ApplicationMonitor
            appMonitor = new ApplicationMonitor();

            // If defined, set a value in property bag.  Used for communication test variations to target app
            if (PropertyBagValue != "")
            {
                // Update this code to allow > 1 prop bag values being set at once
                string[] values = PropertyBagValue.Trim().Split('=');
                if (values.Length == 2)
                {
                    DictionaryStore.Current[values[0].Trim()] = values[1].Trim();
                }
                else
                {
                    throw new System.ArgumentException("Values must be a single 'foo=bar' format");
                }
            }

            if (hostingPolicyResetter != null)
            {
                hostingPolicyResetter.Dispose();
            }

            if (StrictHostingMode)
            {
                hostingPolicyResetter = HostingRuntimePolicyHelper.SetHostingRuntimePolicyValues(
                    doNotLaunchV3AppInV4Runtime: true);
            }
            else
            {
                hostingPolicyResetter = HostingRuntimePolicyHelper.SetHostingRuntimePolicyValues(
                    doNotLaunchV3AppInV4Runtime: false);
            }

            // upload files to FileHost is specified and scheme is not local
            if (Scheme != ActivationScheme.Local)
            {
                if (SupportFiles.Length > 0)
                {
                    // Create host to copy files to...
                    fileHost = new FileHost(UserDefinedDirectory, (Scheme == ActivationScheme.HttpInternetExternal));
                    // Upload each file
                    foreach (SupportFile suppFile in SupportFiles)
                    {
                        // Whether to copy foo\bar\baz.xbap to the foo\bar created on the remote machine or just flattened
                        fileHost.PreserveDirectoryStructure = suppFile.PreserveDirectoryStructure;

                        if (suppFile.IncludeDependencies && !string.IsNullOrEmpty(suppFile.TargetDirectory))
                        {
                            GlobalLog.LogEvidence("TargetDirectory with IncludeDependencies not yet implemented");
                            throw new NotImplementedException("TargetDirectory with IncludeDependencies not yet supported");
                        }
                        if (suppFile.CustomTestScratchServerPath == null)
                        {
                            if (suppFile.IncludeDependencies)
                            {
                                fileHost.UploadFileWithDependencies(suppFile.Name);
                            }
                            else
                            {
                                fileHost.UploadFile(suppFile.Name, suppFile.TargetDirectory);
                            }
                        }
                        else
                        {
                            fileHost.UploadFileNonDefaultServer(suppFile.Name, suppFile.CustomTestScratchServerPath);
                        }
                    }
                }

                // If no support files are listed, check the parent steps to see if one is a FileHostStep.
                // If this is the case, no need to upload the files as the FileHostStep has already.
                // Don't set throttle rate; this should be set in the markup for the parent's filehost.
                else
                {
                    LoaderStep parent = this.ParentStep;

                    while (parent != null)
                    {
                        if (parent.GetType() == typeof(Microsoft.Test.Loaders.Steps.FileHostStep))
                        {
                            this.fileHost = ((FileHostStep)parent).fileHost;
                            break;
                        }
                        // Failed to find it in the immediate parent: try til we hit null or the right one
                        parent = parent.ParentStep;
                    }
                }
            }

            // register UIHandlers
            foreach (UIHandler handler in UIHandlers)
            {
                if (handler.NamedRegistration != null)
                {
                    appMonitor.RegisterUIHandler(handler, handler.NamedRegistration, handler.Notification);
                }
                else
                {
                    appMonitor.RegisterUIHandler(handler, handler.ProcessName, handler.WindowTitle, handler.Notification);
                }
            }

            string param = "";

            if (FileName.StartsWith("&") && FileName.EndsWith("&"))
            {
                param = DictionaryStore.Current[FileName.Substring(1, FileName.Length - 2)];
                if (param == null)
                {
                    throw new InvalidOperationException(FileName + " is not defined in the property bag; cannot be used to launch app");
                }
            }
            else
            {
                // Allows for launching things in %program files%, which is localized.
                param = Environment.ExpandEnvironmentVariables(FileName);
            }

            if (Scheme != ActivationScheme.Local)
            {
                FileHostUriScheme hostScheme = FileHostUriScheme.Unc;
                if (Scheme != ActivationScheme.HttpInternetExternal)
                {
                    hostScheme = (FileHostUriScheme)Enum.Parse(typeof(FileHostUriScheme), Scheme.ToString());
                }
                param = fileHost.GetUri(FileName, hostScheme).ToString();
            }

            // Clear the fusion cache by default.  Can be disabled for custom ClickOnce scenarios
            if (ClearFusionCache)
            {
                ApplicationDeploymentHelper.CleanClickOnceCache();
            }

            // Clear IE History but only if specified (defaults to false).  Only matters for history-based navigation
            if (ClearIEHistory)
            {
                ApplicationDeploymentHelper.ClearIEHistory();
            }

            // Launch the appropriate handler...
            switch (Method)
            {
            case ActivationMethod.Launch:
            {
                // This only works for local paths for security reasons.
                if (PresentationHostDebugMode)
                {
                    param = Path.GetFullPath(param);
                    // Workaround ... for some reason on XP64 there's no guarantee that it will actually find PresHost
                    // Even though it verily is in the SysWOW64 directory.  Solution... find the right one before we try
                    string presHostPath = "presentationhost.exe";
                    if ((Environment.OSVersion.Version.Major == 5))
                    {
                        presHostPath = (Directory.GetFiles(Environment.GetEnvironmentVariable("SystemRoot"), "PresentationHost.exe", SearchOption.AllDirectories))[0];
                    }
                    appMonitor.StartProcess(presHostPath, " -debug \"" + param + "\"");
                }
                else
                {
                    // Launch process with specified arguments.  If shell: specified, then start that way.
                    // If the arguments are for the URL, directly concatenate them.
                    if ((Arguments.Length > 6) && (Arguments.ToLowerInvariant().StartsWith("shell:")))
                    {
                        appMonitor.StartProcess(param, Environment.ExpandEnvironmentVariables(Arguments.Substring(6)));
                    }
                    else if ((Arguments.Length > 11) && (Arguments.ToLowerInvariant().StartsWith("currentdir:")))
                    {
                        appMonitor.StartProcess(param, Path.Combine(Environment.CurrentDirectory, Arguments.Substring(11)));
                    }
                    else
                    {
                        appMonitor.StartProcess(param + Arguments);
                    }
                }
                break;
            }

            case ActivationMethod.Navigate:
            {
                // If local we need to fully qualify the path
                if (Scheme == ActivationScheme.Local)
                {
                    param = Path.GetFullPath(param);
                }

                // Fail to IE, since it has far more tests.
                string defaultBrowserExecutable = "iexplore.exe";

                try
                {
                    defaultBrowserExecutable = Registry.GetValue(@"HKEY_CURRENT_USER\Software\Clients\StartMenuInternet", null, "iexplore.exe").ToString();
                }
                catch (Exception)
                {
                    try
                    {
                        defaultBrowserExecutable = Registry.GetValue(@"HKEY_LOCAL_MACHINE\Software\Clients\StartMenuInternet", null, "iexplore.exe").ToString();
                    }
                    catch (Exception)
                    {
                        // Do nothing, some machines have been seen in weird states where this is undefined.  Log it anyways.
                        GlobalLog.LogDebug("Unable to get StartMenuInternet key, FireFox or other non-standard browser tests may be affected.  Contact Microsoft if this is the case");
                    }
                }
                // Handle the case where this value exists but isnt set to anything usable.  IE is far more common so fall back to it.
                if (string.IsNullOrEmpty(defaultBrowserExecutable))
                {
                    defaultBrowserExecutable = "iexplore.exe";
                }

                // start the default browser... currently just FF or IE.
                if (defaultBrowserExecutable.ToLowerInvariant().Contains("iexplore"))
                {
                    // Create & register IE navigation handler
                    // IE can be strange: About:NavigateIE sometimes gets a cancelled navigation
                    // Workaround:  Be less sensitive about the window title we trigger on.
                    appMonitor.RegisterUIHandler(new NavigateIE(param + Arguments), "iexplore", "RegExp:(Internet Explorer)", UIHandlerNotification.All);
                    appMonitor.StartProcess("iexplore.exe", "about:NavigateIE");
                }
                else if (defaultBrowserExecutable.ToLowerInvariant().Contains("firefox"))
                {
                    if (Scheme == ActivationScheme.Unc)
                    {
                        param = param.Replace("file:", "").Replace("/", @"\");
                    }
                }
                else
                {
                    throw new InvalidOperationException("Don't know how to navigate an instance of \"" + defaultBrowserExecutable + "\" browser!!! Contact Microsoft with this message.");
                }

                break;
            }

            // GOTO used here for fallthrough since there's only 2 lines difference.
            case ActivationMethod.EHome:
                goto case ActivationMethod.EHomeFullScreen;

            case ActivationMethod.EHomeFullScreen:
            {
                // If local we need to fully qualify the path
                if (Scheme == ActivationScheme.Local)
                {
                    param = Path.GetFullPath(param);
                }

                // Get a reference to the path for the ehome exe...
                string eHomePath = Environment.GetEnvironmentVariable("SystemRoot") + "\\ehome\\ehshell.exe";

                // Fail hard if EHome isnt present on the system.
                // Need to mark testcases accurately in test DB to avoid this.
                if (!File.Exists(eHomePath))
                {
                    throw new InvalidOperationException("\"Ehome\" or \"EHomeFullScreen\" method selected but case was run on non-Media-Center-enabled SKU! \n Contact Microsoft for more info on this issue.");
                }

                // Construct args with path to content to launch (MUST be a Uri)
                string eHomeArgs = "/url:\"" + param + "\"";

                // Tack on the argument for full screen if requested
                if (Method == ActivationMethod.EHomeFullScreen)
                {
                    eHomeArgs += " /directmedia:general";
                }

                // Start MCE...
                appMonitor.StartProcess(eHomePath, eHomeArgs);
                break;
            }
            }

            // Store the activation path into the property bag.  This way apps or child steps can directly figure out the deployment URI
            DictionaryStore.Current["ActivationStepUri"] = param;

            return(true);
        }