2010-11-06 6 views
16

Sto per eseguire un processo (lame.exe) per codificare un file WAV in MP3.Come acquisire un processo STDOUT e STDERR riga per riga mentre si verificano, durante l'operazione di processo. (C#)

Desidero elaborare STDOUT e STDERR del processo per visualizzare le informazioni di avanzamento.

Devo utilizzare la filettatura? Non riesco a capirlo.

Qualche semplice esempio di codice sarebbe apprezzato.

Grazie

+0

ho trovato il campione [qui] (http://msdn.microsoft.com/en-us/library/system. diagnostics.process% 28v = vs.80% 29.aspx) che mostra come leggere sia stdout che stderr con i thread utili. Vedi anche http://cleancode.sourceforge.net/api/csharp/html/T_CleanCode_IO_ExecProcess.htm. –

risposta

7

Se si esegue tramite la classe Process, è possibile reindirizzare i flussi così si può elaborarli. È possibile leggere da stdout o stderr in modo sincrono o asincrono. Per abilitare il reindirizzamento, imposta le proprietà di reindirizzamento appropriate su true per gli stream che desideri reindirizzare (ad es., RedirectStandardOutput) e imposta UseShellExecute su false. Quindi puoi solo avviare il processo e leggere dagli stream. È anche possibile alimentare l'input reindirizzando lo stdin.

esempio, elaborare e stampare qualunque sia il processo scrive su stdout sincrono

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

Ciò non cattura STDERR. –

+0

@Albin: Beh, ovviamente, non ho scritto l'esempio per farlo. –

1

C'è an MSDN example per questo ... Ecco una versione semplificata:

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

Chiamare sempre "waitForExit' con un timeout per evitare la possibilità di un'attesa infinita. 'waitForExit (10000)' => attende per 10 secondi. –