private RunStatus RunVerifierExecutable(string fullExePath, StringLineReceived stdoutLineReceived, string args = null) { var outStatus = new RunStatus(); using (var proc = new Process()) { var startInfo = new ProcessStartInfo(fullExePath); if (!String.IsNullOrEmpty(args)) startInfo.Arguments = args; startInfo.CreateNoWindow = true; startInfo.UseShellExecute = false; if (stdoutLineReceived != null) { startInfo.RedirectStandardOutput = true; startInfo.StandardOutputEncoding = Encoding.UTF8; proc.OutputDataReceived += (sender, dataArgs) => { stdoutLineReceived(sender, dataArgs.Data); }; } else startInfo.RedirectStandardOutput = false; startInfo.RedirectStandardError = true; startInfo.StandardErrorEncoding = Encoding.UTF8; proc.ErrorDataReceived += (sender, evt) => { if (outStatus.ErrorString == null) outStatus.ErrorString = ""; if (evt.Data == null) { outStatus.ErrorString.TrimEnd('\r', '\n'); return; } outStatus.ErrorString += evt.Data; }; proc.StartInfo = startInfo; proc.Start(); if (startInfo.RedirectStandardOutput) proc.BeginOutputReadLine(); if (startInfo.RedirectStandardError) proc.BeginErrorReadLine(); proc.WaitForExit(); if (startInfo.RedirectStandardError) WaitForProcessEOF(proc, "error"); if (startInfo.RedirectStandardOutput) WaitForProcessEOF(proc, "output"); outStatus.ExitCode = proc.ExitCode; } return outStatus; }
private RunStatus RunCopierExecutable(string fullExePath, StringLineReceived stdoutLineReceived, IEnumerable<string> executableInput = null, bool runAsAdmin = false) { var outStatus = new RunStatus(); using (var proc = new Process()) { string clientGuidStr = Guid.NewGuid().ToString(); ; var stdPipeSvr = new NamedPipeServerStream("Copier_" + clientGuidStr + "_data", PipeDirection.InOut, 1, PipeTransmissionMode.Byte); var errPipeSvr = new NamedPipeServerStream("Copier_" + clientGuidStr + "_error", PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous); proc.StartInfo = new ProcessStartInfo(fullExePath, clientGuidStr); proc.StartInfo.UseShellExecute = true; proc.StartInfo.CreateNoWindow = true; proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; if (runAsAdmin) proc.StartInfo.Verb = "runas"; proc.Start(); var endEvent = new AutoResetEvent(false); errPipeSvr.BeginWaitForConnection(iar => { var pipSvr = (NamedPipeServerStream) iar.AsyncState; try { pipSvr.EndWaitForConnection(iar); var errSb = new StringBuilder(); var readBuffer = new byte[4096]; pipSvr.BeginRead(readBuffer, 0, readBuffer.Length, iar2 => { var pipeStr = (NamedPipeServerStream) iar2.AsyncState; int numBytes = pipeStr.EndRead(iar2); if (numBytes > 0) { string recvStr = Encoding.UTF8.GetString(readBuffer, 0, numBytes); errSb.Append(recvStr); } else //EOF { outStatus.ErrorString = errSb.ToString().TrimEnd('\r', '\n'); pipeStr.Close(); endEvent.Set(); } }, pipSvr); } catch (ObjectDisposedException) { } //happens if no connection happened }, errPipeSvr); stdPipeSvr.WaitForConnection(); if (executableInput != null) { var sw = new StreamWriter(stdPipeSvr, Encoding.UTF8); foreach (string line in executableInput) sw.WriteLine(line); //last one to indicate no more input sw.WriteLine(); sw.Flush(); } stdPipeSvr.WaitForPipeDrain(); //wait for process to read all bytes we sent it using (var sr = new StreamReader(stdPipeSvr, Encoding.UTF8, false)) { while (stdPipeSvr.IsConnected) { string recvLine = sr.ReadLine(); if (stdoutLineReceived != null) stdoutLineReceived(stdPipeSvr, recvLine); if (recvLine == null) break; //EOF } sr.Close(); //closes the underlying named pipe as well } proc.WaitForExit(); outStatus.ExitCode = proc.ExitCode; if (outStatus.ExitCode != 0) endEvent.WaitOne(); //wait for stderr to be read } return outStatus; }