I was trying to put together an interactive Console interceptor/wrapper in C# over the weekend, by re-mixing few code samples I've found in SO and other sites.
With what I've as of now, I'm unable to read back from the console reliably. Any quick pointers?
public class ConsoleInterceptor
{
Process _interProc;
public event Action<string> OutputReceivedEvent;
public ConsoleInterceptor()
{
_interProc = new Process();
_interProc.StartInfo = new ProcessStartInfo("cmd");
InitializeInterpreter();
}
public ConsoleInterceptor(string command)
{
_interProc = new Process();
_interProc.StartInfo = new ProcessStartInfo(command);
InitializeInterpreter();
}
public Process InterProc
{
get
{
return _interProc;
}
}
private void InitializeInterpreter()
{
InterProc.StartInfo.RedirectStandardInput = true;
InterProc.StartInfo.RedirectStandardOutput = true;
InterProc.StartInfo.RedirectStandardError = true;
InterProc.StartInfo.CreateNoWindow = true;
InterProc.StartInfo.UseShellExecute = false;
InterProc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
bool started = InterProc.Start();
Redirect(InterProc.StandardOutput);
Redirect(InterProc.StandardError);
}
private void Redirect(StreamReader input)
{
new Thread((a) =>
{
var buffer = new char[1];
while (true)
{
if (input.Read(buffer, 0, 1) > 0)
OutputReceived(new string(buffer));
};
}).Start();
}
private void OutputReceived(string text)
{
if (OutputReceivedEvent != null)
OutputReceivedEvent(text);
}
public void Input(string input)
{
InterProc.StandardInput.WriteLine(input);
InterProc.StandardInput.Flush();
}
}
What I'm trying to accomplish? Here is a minial use case. Assume that I have two textboxes.
//Create my interceptor
ConsoleInterceptor interc = new ConsoleInterceptor("cmd");
//Show the output in a textbox
interc.OutputReceivedEvent += (data) =>
{
this.Invoke(new Action<string>((s)=> this.textBoxOut.Text += s) ,data);
};
//Capture user input and pass that to the above interceptor
private void textInput_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
interc.Input(textInput.Text);
}
}