/// <summary> /// run cmd and specify the running condition. If running condition is not met, process will be terminated. /// </summary> public static int RunCmd(string cmd, string args, out string stdout, out string stderr, RunningCondition rc, object rcArg) { Test.Logger.Verbose("Running: {0} {1}", cmd, args); ProcessStartInfo psi = new ProcessStartInfo(cmd, args); psi.CreateNoWindow = true; psi.WindowStyle = ProcessWindowStyle.Hidden; psi.UseShellExecute = false; psi.RedirectStandardError = true; psi.RedirectStandardOutput = true; Process p = Process.Start(psi); // To avoid deadlock between Process.WaitForExit and Process output redirection buffer filled up, we need to async read output before calling Process.WaitForExit StringBuilder outputBuffer = new StringBuilder(); p.OutputDataReceived += (sendingProcess, outLine) => { if (!String.IsNullOrEmpty(outLine.Data)) { outputBuffer.Append(outLine.Data + "\n"); } }; StringBuilder errorBuffer = new StringBuilder(); p.ErrorDataReceived += (sendingProcess, outLine) => { if (!String.IsNullOrEmpty(outLine.Data)) { errorBuffer.Append(outLine.Data + "\n"); } }; p.BeginOutputReadLine(); p.BeginErrorReadLine(); DateTime nowTime = DateTime.Now; DateTime timeOut = nowTime.AddMilliseconds(RUNCMD_TIMEOUT_MS); while (rc(rcArg)) { if (p.HasExited) { // process has existed break; } else if (timeOut > DateTime.Now) { //time out break; } else { //continue to wait Thread.Sleep(100); } } stdout = outputBuffer.ToString(); stderr = errorBuffer.ToString(); if (p.HasExited) { Test.Logger.Verbose("Stdout: {0}", stdout); if (!string.IsNullOrEmpty(stderr) && !string.Equals(stdout, stderr, StringComparison.InvariantCultureIgnoreCase)) Test.Logger.Verbose("Stderr: {0}", stderr); return p.ExitCode; } else { Test.Logger.Verbose("--Command timed out!"); p.Kill(); Test.Logger.Verbose("Stdout: {0}", stdout); if (!string.IsNullOrEmpty(stderr) && !string.Equals(stdout, stderr, StringComparison.InvariantCultureIgnoreCase)) Test.Logger.Verbose("Stderr: {0}", stderr); return int.MinValue; } }
/// <summary> /// run cmd and specify the running condition. If running condition is not met, process will be terminated. /// </summary> public static int RunCmd(string cmd, string args, out string stdout, out string stderr, RunningCondition rc, object rcArg) { Test.Logger.Verbose("Running: {0} {1}", cmd, args); ProcessStartInfo psi = new ProcessStartInfo(cmd, args); psi.CreateNoWindow = true; psi.WindowStyle = ProcessWindowStyle.Hidden; psi.UseShellExecute = false; psi.RedirectStandardError = true; psi.RedirectStandardOutput = true; Process p = Process.Start(psi); // To avoid deadlock between Process.WaitForExit and Process output redirection buffer filled up, we need to async read output before calling Process.WaitForExit StringBuilder outputBuffer = new StringBuilder(); p.OutputDataReceived += (sendingProcess, outLine) => { if (!String.IsNullOrEmpty(outLine.Data)) { outputBuffer.Append(outLine.Data + "\n"); } }; StringBuilder errorBuffer = new StringBuilder(); p.ErrorDataReceived += (sendingProcess, outLine) => { if (!String.IsNullOrEmpty(outLine.Data)) { errorBuffer.Append(outLine.Data + "\n"); } }; p.BeginOutputReadLine(); p.BeginErrorReadLine(); DateTime nowTime = DateTime.Now; DateTime timeOut = nowTime.AddMilliseconds(RUNCMD_TIMEOUT_MS); while (rc(rcArg)) { if (p.HasExited) { // process has existed break; } else if (timeOut > DateTime.Now) { //time out break; } else { //continue to wait Thread.Sleep(100); } } stdout = outputBuffer.ToString(); stderr = errorBuffer.ToString(); if (p.HasExited) { Test.Logger.Verbose("Stdout: {0}", stdout); if (!string.IsNullOrEmpty(stderr) && !string.Equals(stdout, stderr, StringComparison.InvariantCultureIgnoreCase)) { Test.Logger.Verbose("Stderr: {0}", stderr); } return(p.ExitCode); } else { Test.Logger.Verbose("--Command timed out!"); p.Kill(); Test.Logger.Verbose("Stdout: {0}", stdout); if (!string.IsNullOrEmpty(stderr) && !string.Equals(stdout, stderr, StringComparison.InvariantCultureIgnoreCase)) { Test.Logger.Verbose("Stderr: {0}", stderr); } return(int.MinValue); } }