예제 #1
0
            public void SetUp()
            {
                terminatedSuccessfully = new ManualResetEvent(false);

                processTask = Tasks.StartProcessTask(Path.Combine(Environment.SystemDirectory, "cmd.exe"),
                    "/C exit " + COR_E_STACKOVERFLOW, Environment.CurrentDirectory);
                processTask.Terminated += processTask_Terminated;
                processTask.Start();
                Assert.IsTrue(processTask.Join(TimeSpan.FromSeconds(10)), "Wait for exit");
            }
예제 #2
0
        /// <inheritdoc />
        public IVisualStudio LaunchVisualStudio(VisualStudioVersion version, ILogger logger)
        {
            if (logger == null)
                throw new ArgumentNullException("logger");

            Pair<string, VisualStudioVersion>? installDirAndVersion = GetVisualStudioInstallDirAndVersion(version);
            if (!installDirAndVersion.HasValue)
            {
                logger.Log(LogSeverity.Debug, string.Format("Could not find Visual Studio version '{0}'.", version));
                return null;
            }

            string devenvPath = Path.Combine(installDirAndVersion.Value.First, "devenv.exe");
            ProcessTask devenvProcessTask = new ProcessTask(devenvPath, "", Environment.CurrentDirectory);

            logger.Log(LogSeverity.Debug, string.Format("Launching Visual Studio using path: '{0}'.", devenvProcessTask.ExecutablePath));
            devenvProcessTask.Start();

            System.Diagnostics.Process devenvProcess = devenvProcessTask.Process;
            if (devenvProcess != null)
            {
                int processId = devenvProcess.Id;

                Stopwatch stopwatch = Stopwatch.StartNew();
                for (;;)
                {
                    IVisualStudio visualStudio = GetVisualStudioFromProcess(processId, installDirAndVersion.Value.Second, true, logger);
                    if (visualStudio != null)
                        return visualStudio;

                    if (stopwatch.ElapsedMilliseconds > VisualStudioAttachTimeoutMilliseconds)
                    {
                        logger.Log(LogSeverity.Debug, string.Format("Stopped waiting for Visual Studio to launch after {0} milliseconds.", VisualStudioAttachTimeoutMilliseconds));
                        break;
                    }

                    if (!devenvProcessTask.IsRunning)
                        break;

                    Thread.Sleep(500);
                }
            }

            if (devenvProcessTask.IsTerminated && devenvProcessTask.Result != null)
            {
                if (! devenvProcessTask.Result.HasValue)
                    logger.Log(LogSeverity.Debug, "Failed to launch Visual Studio.", devenvProcessTask.Result.Exception);
            }

            return null;
        }
예제 #3
0
        private void FreeResources(bool abortImmediately)
        {
            if (processTask != null)
            {
                if (! abortImmediately)
                {
                    if (!processTask.Join(JoinBeforeAbortWarningTimeout))
                    {
                        Logger.Log(LogSeverity.Info, "Waiting for the host process to terminate.");
                        if (!processTask.Join(JoinBeforeAbortTimeout - JoinBeforeAbortWarningTimeout))
                            Logger.Log(LogSeverity.Info, string.Format("Timed out after {0} minutes.", JoinBeforeAbortTimeout.TotalMinutes));
                    }
                }

                if (! processTask.Join(TimeSpan.Zero))
                {
                    Logger.Log(LogSeverity.Warning, "Forcibly killing the host process!");
                    processTask.Abort();
                    processTask.Join(JoinAfterAbortTimeout);
                }

                processTask = null;
            }

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

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

            if (temporaryConfigurationFilePath != null)
            {
                File.Delete(temporaryConfigurationFilePath);
                temporaryConfigurationFilePath = null;
            }

            lock (logConsoleOutputBufferTimer)
            {
                logConsoleOutputBufferTimer.Dispose();
            }
        }
예제 #4
0
        private void StartProcess(string hostConnectionArguments)
        {
            bool useElevation = HostSetup.Elevated && !DotNetRuntimeSupport.IsUsingMono;

            CreateTemporaryConfigurationFile();

            StringBuilder hostArguments = new StringBuilder();
            hostArguments.Append(hostConnectionArguments);

            if (HostSetup.DebuggerSetup == null)
                hostArguments.Append(@" /timeout:").Append((int)WatchdogTimeout.TotalSeconds);

            hostArguments.Append(@" /owner-process:").Append(Process.GetCurrentProcess().Id);

            if (HostSetup.ApplicationBaseDirectory != null)
                hostArguments.Append(@" /application-base-directory:""").Append(
                    FileUtils.StripTrailingBackslash(HostSetup.ApplicationBaseDirectory)).Append('"');
            
            foreach (string hintDirectory in HostSetup.HintDirectories)
                hostArguments.Append(@" /hint-directory:""").Append(
                    FileUtils.StripTrailingBackslash(hintDirectory)).Append('"');

            hostArguments.Append(@" /configuration-file:""").Append(temporaryConfigurationFilePath).Append('"');

            if (HostSetup.ShadowCopy)
                hostArguments.Append(@" /shadow-copy");

            if (HostSetup.DebuggerSetup != null)
                hostArguments.Append(@" /debug");

            hostArguments.Append(" /severity-prefix");

            if (useElevation)
                hostArguments.Append(" /quiet");

            severityPrefixParser = new SeverityPrefixParser();

            processTask = CreateProcessTask(GetInstalledHostProcessPath(), hostArguments.ToString(), HostSetup.WorkingDirectory ?? Environment.CurrentDirectory);
            processTask.Terminated += HandleProcessExit;

            if (useElevation)
            {
                if (HostSetup.RuntimeVersion != null)
                    throw new HostException("The host does not support a non-default RuntimeVersion with Elevation.");

                processTask.UseShellExecute = true;
                processTask.ConfigureProcessStartInfo += (sender, e) =>
                {
                    e.ProcessStartInfo.Verb = "runas";
                    e.ProcessStartInfo.ErrorDialog = true;
                    e.ProcessStartInfo.ErrorDialogParentHandle = GetOwnerWindowHandle();
                };
            }
            else
            {
                processTask.CaptureConsoleOutput = true;
                processTask.CaptureConsoleError = true;
                processTask.ConsoleOutputDataReceived += LogConsoleOutput;
                processTask.ConsoleErrorDataReceived += LogConsoleError;

                // Force CLR runtime version.
                string runtimeVersion = HostSetup.RuntimeVersion;
                if (runtimeVersion == null)
                    runtimeVersion = DotNetRuntimeSupport.MostRecentInstalledDotNetRuntimeVersion;

                if (!runtimeVersion.StartsWith("v"))
                    runtimeVersion = "v" + runtimeVersion; // just in case, this is a common user error

                // http://msdn.microsoft.com/en-us/library/w4atty68.aspx
                if (runtimeVersion == "v4.0")
                    runtimeVersion = "v4.0.30319";

                processTask.SetEnvironmentVariable("COMPLUS_Version", runtimeVersion);
            }

            processTask.Start();
        }
예제 #5
0
        private static void ConfigureProcessTaskForLogging(ProcessTask task, MarkupStreamWriter writer)
        {
            task.Started += delegate
            {
                writer.BeginSection(String.Format("Run Process: {0} {1}", task.ExecutablePath, task.Arguments));
                writer.WriteLine("Working Directory: {0}", task.WorkingDirectory);
                writer.BeginMarker(Marker.Monospace);
            };

            task.ConsoleOutputDataReceived += delegate(object sender, DataReceivedEventArgs e)
            {
                if (e.Data != null)
                    writer.WriteLine(e.Data);
            };

            task.ConsoleErrorDataReceived += delegate(object sender, DataReceivedEventArgs e)
            {
                if (e.Data != null)
                    writer.WriteLine(e.Data);
            };

            task.Aborted += delegate
            {
                if (task.IsRunning)
                    writer.BeginSection("Abort requested.  Killing the process!").Dispose();
            };

            task.Terminated += delegate
            {
                writer.End();
                writer.WriteLine("Exit Code: {0}", task.ExitCode);
                writer.End();
            };
        }
예제 #6
0
        /// <summary>
        /// Creates a new process task but does not start it.
        /// </summary>
        /// <remarks>
        /// <para>
        /// The output of the process will be logged and included as part of the test results.  It
        /// may also be examined using the <see cref="ProcessTask.ConsoleOutput" /> and
        /// <see cref="ProcessTask.ConsoleError" /> properties while the process executes and
        /// after it terminates.
        /// </para>
        /// <para>
        /// There is no need to call <see cref="WatchTask" /> on the returned task.
        /// </para>
        /// </remarks>
        /// <param name="executablePath">The path of the executable executable.</param>
        /// <param name="arguments">The arguments for the executable.</param>
        /// <param name="workingDirectory">The working directory.</param>
        /// <returns>The new thread task.</returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="executablePath"/>,
        /// <paramref name="arguments"/> or <paramref name="workingDirectory"/> is null.</exception>
        public static ProcessTask CreateProcessTask(string executablePath, string arguments, string workingDirectory)
        {
            if (executablePath == null)
                throw new ArgumentNullException("executablePath");
            if (arguments == null)
                throw new ArgumentNullException("arguments");
            if (workingDirectory == null)
                throw new ArgumentNullException("workingDirectory");

            var task = new ProcessTask(executablePath, arguments, workingDirectory);
            task.CaptureConsoleOutput = true;
            task.CaptureConsoleError = true;

            ConfigureProcessTaskForLogging(task, TestLog.Default);
            WatchTask(task);
            return task;
        }