I am attempting to redirect a process running a command prompt to output to a WPF textbox. I found some very helpful code in a previous question here that got me most of the way. The redirect works, but only up until the end of the first line. For instance. If I direct the process to run cmd.exe /c ipconfig, only "Windows IP Configuration" is added to the textbox and not the full output of the command. The classes that deal with redirection are identical to the response in the previous question:
public class ConsoleInputReadEventArgs : EventArgs
{
public ConsoleInputReadEventArgs(string input)
{
this.Input = input;
}
public string Input { get; private set; }
}
public interface IConsoleAutomator
{
StreamWriter StandardInput { get; }
event EventHandler<ConsoleInputReadEventArgs> StandardInputRead;
}
public abstract class ConsoleAutomatorBase : IConsoleAutomator
{
protected readonly StringBuilder inputAccumulator = new StringBuilder();
protected readonly byte[] buffer = new byte[1024];
protected volatile bool stopAutomation;
public StreamWriter StandardInput { get; protected set; }
protected StreamReader StandardOutput { get; set; }
protected StreamReader StandardError { get; set; }
public event EventHandler<ConsoleInputReadEventArgs> StandardInputRead;
protected void BeginReadAsync()
{
if (!this.stopAutomation)
{
this.StandardOutput.BaseStream.BeginRead(this.buffer, 0, this.buffer.Length, this.ReadHappened, null);
}
}
protected virtual void OnAutomationStopped()
{
this.stopAutomation = true;
this.StandardOutput.DiscardBufferedData();
}
private void ReadHappened(IAsyncResult asyncResult)
{
var bytesRead = this.StandardOutput.BaseStream.EndRead(asyncResult);
if (bytesRead == 0)
{
this.OnAutomationStopped();
return;
}
var input = this.StandardOutput.CurrentEncoding.GetString(this.buffer, 0, bytesRead);
this.inputAccumulator.Append(input);
if (bytesRead < this.buffer.Length)
{
this.OnInputRead(this.inputAccumulator.ToString());
}
this.BeginReadAsync();
}
private void OnInputRead(string input)
{
var handler = this.StandardInputRead;
if (handler == null)
{
return;
}
handler(this, new ConsoleInputReadEventArgs(input));
this.inputAccumulator.Clear();
}
}
public class ConsoleAutomator : ConsoleAutomatorBase, IConsoleAutomator
{
public ConsoleAutomator(StreamWriter standardInput, StreamReader standardOutput)
{
this.StandardInput = standardInput;
this.StandardOutput = standardOutput;
}
public void StartAutomate()
{
this.stopAutomation = false;
this.BeginReadAsync();
}
public void StopAutomation()
{
this.OnAutomationStopped();
}
}
I am creating my process and using an event handler to direct the output to the textbox in my GUI here:
private void runCMD(string command)
{
var processStartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Verb = "runas",
Arguments = "/C " + command,
RedirectStandardInput = true,
RedirectStandardOutput = true,
UseShellExecute = false
};
var process = Process.Start(processStartInfo);
var automator = new ConsoleAutomator(process.StandardInput, process.StandardOutput);
automator.StandardInputRead += AutomatorStandardInputRead;
automator.StartAutomate();
process.WaitForExit();
automator.StandardInputRead -= AutomatorStandardInputRead;
process.Close();
}
private void AutomatorStandardInputRead(object sender, ConsoleInputReadEventArgs e)
{
this.Dispatcher.Invoke(() => {
consoleWindow.Text += e.Input.ToString();
});
}
Can someone explain what I am missing? Thank you in advance.