В течение выходных я пытался собрать интерактивный консольный перехватчик / упаковщик в C #, повторно смешав несколько примеров кода, которые я нашел на SO и других сайтах.
С тем, что у меня есть сейчас, я не могу надежно читать с консоли. Есть быстрые указатели?
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();
}
}
Чего я пытаюсь достичь? Вот минимальный вариант использования. Предположим, у меня есть два текстовых поля.
//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);
}
}