Проблема, с которой вы столкнулись, заключается в том, что класс Process
настроен для удобной линейно-ориентированной обработки событий процесса. Вы не можете использовать эту функцию, если вам нужно читать частичные строки, когда они выводятся.
Тем не менее, класс Process
дает вам необходимые инструменты, если вам нужен более точный контроль над выходом, чем в линейных объектах. Если вы перенаправите вывод, то Process.StandardOutput
- это StreamReader
, и у вас есть весь API-интерфейс StreamReader
, который вы можете использовать вместо необходимости читать целые строки.
Например, здесь посимвольное чтение стандартного вывода:
var start = DateTime.Now;
int n;
while ((n = ServerProc.StandardOutput.Read()) != -1)
{
var c = (char)n;
var delta = (DateTime.Now - start).TotalMilliseconds;
Console.WriteLine("c = {0} (0x{1:X}) delta = {2}",
char.IsWhiteSpace(c) ? '*' : c, n, delta);
}
Если мы запустим его в другой консольной программе, которая выдаст этот вывод:
Console.Write("abc");
Thread.Sleep(1000);
Console.WriteLine("def");
Он производит такой вывод:
c = a (0x61) delta = 44.0025
c = b (0x62) delta = 44.0025
c = c (0x63) delta = 44.0025
c = d (0x64) delta = 1109.0634
c = e (0x65) delta = 1110.0635
c = f (0x66) delta = 1110.0635
c = * (0xD) delta = 1110.0635
c = * (0xA) delta = 1110.0635
, который показывает, что "abc"
был прочитан за одну секунду до остальной части строки.
Однако это не удобно, если вам нравится ориентированный на события ввод-вывод, уже предоставленный Process
. Вы можете либо:
- использовать асинхронный
Stream
API
- использовать потоки, которые блокируют чтение
и, возможно, даже сверните свой собственный ввод-вывод на основе событий, который соответствует вашим потребностям.
Вы пишете программу, которая анализирует символьно-ориентированный вывод другой программы, и поэтому без полных строк вам понадобится какой-то тайм-аут, чтобы указать: «Теперь я удовлетворен тем, что программа на данный момент производит вывод». Это может быть легко или сложно в зависимости от того, насколько предсказуемым будет результат. Например, вы можете распознать приглашение, оканчивающееся на "?"
. Это зависит от вашей ситуации.
Дело в том, что вам придется использовать свойства StandardOutput
и StandardError
StreamReader
, если вы хотите что-то отличное от линейно-ориентированного ввода / вывода.