Доброго времени суток!
Столкнулся со стандартной избитой задачей, но ни один ответ на форумах не помогает решить её правильно.
Цель: запустить некоторое консольное приложение (написанное не мною) и перенаправить его выходной поток (StreamReader) в предназначенный для этого WPF-control моего окна(например RichTextBox), чтобы последний работал real-time.
(т.е. обрабатывать даже Write, а не только WriteLine. например tracert)
=============
Возможные варианты:
1) асинхронный Process.BeginOutputReadLine (не подходит, т.к. получает данные целыми строками. вызовы Write будут обрабатываться не своевременно)
2) синхронный Process.StandardOutput.ReadLine (не подходит по той же причине), Process.StandardOutput.ReadToEnd туда же.
3) Process.StandardOutput.Read/ReadBlock см. ниже.
4) мб можно забиндить StreamReader к RichTextBox, но я понятия не имею как.
5) сделать совсем как-то иначе.
=============
С Process.StandardOutput.Read набросал такой код:
BackgroundWorker workerOutput = new BackgroundWorker();
BackgroundWorker workerError = new BackgroundWorker();
Process proc = new Process();
private void Window_Loaded(object sender, RoutedEventArgs e)
{
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.WorkingDirectory = @"D:\Development";
bool started;
started = proc.Start();
if (started == true)
{
workerOutput.WorkerSupportsCancellation = true;
workerError.WorkerSupportsCancellation = true;
workerOutput.DoWork += new DoWorkEventHandler(threadOutput);
workerError.DoWork += new DoWorkEventHandler(threadOutput);
workerOutput.RunWorkerAsync(0);
workerError.RunWorkerAsync(1);
}
}
delegate void GUIUpdate(string str);
private void threadOutput(object sender, System.ComponentModel.DoWorkEventArgs args)
{
const int bufferSize = 9;
char[] buffer = new char[bufferSize];
int count = 0;
string str;
GUIUpdate textBoxUpdate = (string s) =>
{
richTextBox4.AppendText(s);
richTextBox4.ScrollToEnd();
};
switch ((int)args.Argument)
{
case 0:
while (!workerOutput.CancellationPending)
{
count = proc.StandardOutput.Read(buffer, 0, bufferSize);
str = new string(buffer, 0, count);
richTextBox4.Dispatcher.BeginInvoke(textBoxUpdate, str);
}
break;
case 1:
while (!workerOutput.CancellationPending)
{
count = proc.StandardError.Read(buffer, 0, bufferSize);
str = new string(buffer, 0, count);
richTextBox4.Dispatcher.BeginInvoke(textBoxUpdate, str);
}
break;
}
}
Проблема заключается в том, что в зависимости от величины bufferSize я разное кол-во данных.
[bufferSize = 9]
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
D:\Develo
[bufferSize = 3]
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
D:\Development>
[bufferSize = 10, один раз вызван proc.StandardInput.WriteLine("");]
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
D:\Development>
D:\Develop
Почему данные зависят от размера буфера? и как можно это исправить? (или решить задачу как-то иначе)
Спасибо