Частично читать стандартный вывод другого процесса, созданного из приложения c # - PullRequest
1 голос
/ 09 марта 2009

У меня есть приложение с графическим интерфейсом, в котором я запускаю консольное приложение, используя класс Process.

Process p1 = new Process();
p1.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p1.StartInfo.CreateNoWindow = true;
p1.StartInfo.UseShellExecute = false;
p1.StartInfo.FileName = Path.Combine(basepath, "abc.exe");
p1.StartInfo.Arguments = "/pn abc.exe /f \"temp1.txt\"";
p1.StartInfo.RedirectStandardError = true;
p1.StartInfo.RedirectStandardInput = true;
p1.StartInfo.RedirectStandardOutput = true;
p1.OutputDataReceived += new DataReceivedEventHandler(outputreceived);
p1.ErrorDataReceived += new DataReceivedEventHandler(errorreceived);
p1.Start();
tocmd = p1.StandardInput;
p1.BeginOutputReadLine();
p1.BeginErrorReadLine();

Теперь у меня проблема в том, что, хотя он читает данные консоли асинхронно, но, похоже, запускает событие только тогда, когда внутренний буфер заполнен некоторым количеством. Я хочу, чтобы он отображал данные по мере поступления. Если в буфере 10 байтов, пусть он отображает 10 байтов. Моя программа реализует внутренний вызов sleep (), поэтому мне нужно распечатать данные, пока они не перейдут в спящий режим.

Как я могу это сделать?

=============

Как уже упоминалось, вывод буферизован строкой, я попробовал следующее изменение в коде

p1.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p1.StartInfo.CreateNoWindow = true;
p1.StartInfo.UseShellExecute = false;
p1.StartInfo.FileName = Path.Combine(basepath, "abc.exe");
p1.StartInfo.Arguments = pnswitch + " /f \"temp1.txt\"";
p1.StartInfo.RedirectStandardError = false;
p1.StartInfo.RedirectStandardInput = true;
p1.StartInfo.RedirectStandardOutput = true;
p1.Start();
tocmd = p1.StandardInput;
MethodInvoker mi = new MethodInvoker(readout);
mi.BeginInvoke(null, p1);

и внутри показания я написал

void readout()
    {
        string str;
        while ((str = p1.StandardOutput.ReadLine()) != null)
        {
            richTextBox1.Invoke(new UpdateOutputCallback(this.updateoutput), new object[] { str });
            p1.StandardOutput.BaseStream.Flush();
        }
    }

Так что я думаю, что теперь он отслеживает, когда пишется каждая строка, и печатает это правильно? это тоже не сработало. Что-то не так?

Ответы [ 2 ]

3 голосов
/ 09 марта 2009

Полученные выходные данные и данные об ошибках буферизуются строкой и срабатывают только при добавлении новой строки.

Лучше всего использовать собственный ридер, который может читать ввод, побайтно. Очевидно, это должно быть неблокирующим:)

1 голос
/ 09 марта 2009

Для этого необходимо использовать синхронные операции чтения в перенаправленном потоке. Ваш код будет выглядеть так (пример MSDN):

// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "Write500Lines.exe";
p.Start();
// Do not wait for the child process to exit before
// reading to the end of its redirected stream.
// p.WaitForExit();
// Read the output stream first and then wait.
**string output = p.StandardOutput.ReadToEnd();**
p.WaitForExit();

Чтобы добиться асинхронного поведения, вам нужно использовать несколько потоков.

MSDN Артикул здесь

...