2010-11-06 1 views
16

Я собираюсь выполнить Process (lame.exe), чтобы закодировать WAV-файл в MP3.Как захватить процессы STDOUT и STDERR по очереди, когда они происходят, во время процесса. (C#)

Я хочу обработать STDOUT и STDERR процесса для отображения информации о ходе работы.

Нужно ли использовать резьбу? Я не могу обдумать это.

Простой примерный код будет оценен.

Благодаря

+0

Я нашел образец [здесь] (http://msdn.microsoft.com/en-us/library/system. диагностика.процесс% 28v = vs.80% 29.aspx), который показывает, как читать как stdout, так и stderr с помощью потоков. См. Также http://cleancode.sourceforge.net/api/csharp/html/T_CleanCode_IO_ExecProcess.htm. –

ответ

7

При работе через Process класса, вы можете перенаправить потоки, так что вы можете обработать их. Вы можете читать из stdout или stderr синхронно или асинхронно. Чтобы включить перенаправление, установите соответствующие свойства перенаправления на true для потоков, которые вы хотите перенаправить (например, RedirectStandardOutput) и установите UseShellExecute в false. Затем вы можете просто начать процесс и прочитать из потоков. Вы также можете подавать входной перенаправление stdin.

например, процесс и печать любой процесс записывает в стандартный вывод синхронно

var proc = new Process() 
{ 
    StartInfo = new ProcessStartInfo(@"SomeProcess.exe") 
    { 
     RedirectStandardOutput = true, 
     UseShellExecute = false, 
    } 
}; 
if (!proc.Start()) 
{ 
    // handle error 
} 
var stdout = proc.StandardOutput; 
string line; 
while ((line = stdout.ReadLine()) != null) 
{ 
    // process and print 
    Process(line); 
    Console.WriteLine(line); 
} 
+11

Это не захватывает STDERR. –

+0

@ Албин: Ну, очевидно, я не написал пример, чтобы сделать это. –

1

Существует an MSDN example для этого ... Вот упрощенная версия:

var StdOut = ""; 
var StdErr = ""; 

var stdout = new StringBuilder(); 
var stderr = new StringBuilder(); 

var psi = new ProcessStartInfo(); 
psi.FileName = @"something.exe"; 
psi.CreateNoWindow = true; 
psi.UseShellExecute = false; 
psi.RedirectStandardOutput = true; 
psi.RedirectStandardError = true; 

var proc = new Process(); 
proc.StartInfo = psi; 
proc.OutputDataReceived += (sender, e) => { stdout.AppendLine(e.Data); }; 
proc.ErrorDataReceived += (sender, e) => { stderr.AppendLine(e.Data); }; 
proc.Start(); 
proc.BeginOutputReadLine(); 
proc.BeginErrorReadLine(); 
proc.WaitForExit(10000); // per sachin-joseph's comment 

StdOut = stdout.ToString(); 
StdErr = stderr.ToString(); 
+0

Всегда вызывайте 'waitForExit' с таймаутом, чтобы предотвратить вероятность бесконечного ожидания. 'waitForExit (10000)' => ждет 10 секунд. –