예제 #1
0
 public ProcessResult RunProcess(CommandLineOutputCaptureOptionsFlag captureOptionsFlag)
 {
     _lastProcessResult = RunProcess(_workingDirectory.FullName, _executibleFile.FullName, CommandLineArgumentsAsString, null, captureOptionsFlag);
     return(_lastProcessResult);
 }
예제 #2
0
        private static ProcessResult RunProcess(string workingDirectory, string exeFileName, string argumentsAsString, int?maxTimeoutMs, CommandLineOutputCaptureOptionsFlag captureOptionsFlag)
        {
            // Start the indicated program and wait for it
            // to finish, hiding while we wait.
            ProcessResult r;

            using (var processWrapper = new KillOnDisposeProcessWrapper(new Process {
                StartInfo = new ProcessStartInfo(exeFileName, argumentsAsString)
            }))
            {
                if (!String.IsNullOrEmpty(workingDirectory))
                {
                    processWrapper.Process.StartInfo.WorkingDirectory = workingDirectory;
                }
                var outputSink = new ProcessStreamReader(captureOptionsFlag);
                processWrapper.Process.StartInfo.UseShellExecute        = false;
                processWrapper.Process.StartInfo.RedirectStandardOutput = true;
                processWrapper.Process.StartInfo.RedirectStandardError  = true;
                processWrapper.Process.StartInfo.CreateNoWindow         = true;
                processWrapper.Process.OutputDataReceived += outputSink.ReceiveStdOut;
                processWrapper.Process.ErrorDataReceived  += outputSink.ReceiveStdErr;

                var processDebugInfo = String.Format("Process Details:\r\n\"{0}\" {1}\r\nWorking Directory: {2}", exeFileName, argumentsAsString, workingDirectory);
                try
                {
                    processWrapper.Process.Start();
                }
                catch (Exception e)
                {
                    var message = String.Format("Program {0} got an exception on process start.\r\nException message: {1}\r\n{2}", Path.GetFileName(exeFileName), e.Message, processDebugInfo);
                    throw new Exception(message, e);
                }

                processWrapper.Process.BeginOutputReadLine();
                processWrapper.Process.BeginErrorReadLine();

                var processTimeoutPeriod = (maxTimeoutMs.HasValue) ? TimeSpan.FromMilliseconds(maxTimeoutMs.Value) : _maxTimeout;
                var hasExited            = processWrapper.Process.WaitForExit(Convert.ToInt32(processTimeoutPeriod.TotalMilliseconds));

                if (!hasExited)
                {
                    processWrapper.Process.Kill();
                }

                // TODO: Fix this so it works without a hacky "Sleep", right now this hack waits for the output to trickle in. The asychronous reads of STDERR and STDOUT may not yet be complete (run unit test under debugger for example) even though the process has exited. -MF & ASW 11/21/2011
                Thread.Sleep(TimeSpan.FromSeconds(.25));

                if (!hasExited)
                {
                    var message = String.Format("Program {0} did not exit within timeout period {1} and was terminated.\r\n{2}\r\nOutput:\r\n{3}", Path.GetFileName(exeFileName), processTimeoutPeriod,
                                                processDebugInfo, outputSink.StdOutAndStdErr);
                    throw new Exception(message);
                }

                r = new ProcessResult(processWrapper.Process.ExitCode, outputSink.StdOut, outputSink.StdErr, outputSink.StdOutAndStdErr);
            }
            return(r);
        }
예제 #3
0
 public ProcessStreamReader(CommandLineOutputCaptureOptionsFlag captureOptionsFlag)
 {
     _captureOptionsFlag = captureOptionsFlag;
 }