2009-04-24 6 views
5

Ich spawne einen untergeordneten Prozess, der in einem sichtbaren Konsolenfenster ausgeführt wird (es ist eine Batchdatei, die MSBuild ausführt), und ich möchte die Ausgabe von der Prozess wird im sichtbaren Konsolenfenster angezeigt und erfasst diese Ausgabe, so dass ich sie im Code verarbeiten kann. Ich habe einige andere Fragen und die MSDN-Dokumentation mit ProcessStartInfo.RedirectStandardOutput und dergleichen zu tun zu lesen, und ich kann die Ausgabe aus dem umgeleiteten Strom erfassen und es in Code verarbeiten ganz gut:Erfassen Sie die Standardausgabe und zeigen Sie sie immer noch im Konsolenfenster an.

Process msBuild = new Process(); 
msBuild.StartInfo.FileName = "Build.bat"; 
msBuild.StartInfo.UseShellExecute = false; 
msBuild.StartInfo.RedirectStandardOutput = true; 
msBuild.Start(); 
string output = msBuild.StandardOutput.ReadToEnd(); 
msBuild.WaitForExit(); 

Das Problem ist, dass die Ausgabe wird nicht im Konsolenfenster des Kindprozesses angezeigt; Ich bekomme nur ein leeres Konsolenfenster auf dem Bildschirm, während der Prozess läuft, der nach Beendigung des Prozesses verschwindet.

Ich nehme an, ich könnte das tatsächliche untergeordnete Prozessfenster ausblenden und ein zweites Fenster anzeigen, dass ich einfach die Ausgabe schreiben würde, wie es erfasst wurde, aber das scheint mehr Arbeit als nötig. Gibt es eine Möglichkeit, die Ausgabe im Konsolenfenster anzuzeigen und sie dennoch für die Verarbeitung zu erfassen, wenn sie fertig ist?

Antwort

3

Sobald Sie den Standard umgeleitet haben, ist er nicht mehr auf die Konsole gerichtet. Um auf die Konsole zu schreiben, müssen Sie es manuell tun.

Wenn Sie die Ausgabe anzeigen möchten, während der Prozess ausgeführt wird, können Sie anstelle eines großen Dumps am Ende das Ereignis "OutputDataReceived" der Process-Klasse verwenden.

+0

Wow - ich hatte vorher nicht gesehen OutputDataReceived. Ordentlich! –

+0

Das scheint die Frage zu beantworten, ob ich die Ausgabe im Konsolenfenster anzeigen lassen kann, die dem Kindprozess gehört, und gleichzeitig zum übergeordneten Prozess umgeleitet wird. Meine nächste Frage wäre, ist es möglich, die Ausgabe nicht umzuleiten, und nur alles von der Konsole erfassen, wenn der Prozess beendet? Oder, wenn nicht, was ist der beste Weg, um ein Konsolenfenster manuell zu erstellen, so dass ich die umgeleitete Ausgabe zu schreiben kann, während der Prozess ausgeführt wird (mit 'OutputDataReceived')? – mjl5007

+1

Werfen Sie einen Blick auf http://msdn.microsoft.com/en-us/library/system.diagnostics.process.outputdatareceived.aspx. Es hat ein Beispiel (Sie möchten vielleicht alle Sprachen außer C# ausschalten) –

4

Hier ist, was ich verwendet habe, ohne einen separaten Thread mit:


using(System.Diagnostics.Process proc = new System.Diagnostics.Process()) 
{ 
    proc.EnableRaisingEvents = false; 
    proc.StartInfo.RedirectStandardOutput = true; 
    proc.StartInfo.CreateNoWindow = true; 
    proc.StartInfo.UseShellExecute = false; 
    proc.StartInfo.Verb = "open"; 
    proc.StartInfo.FileName = "XXXX"; 
    proc.Start(); 
    String sLine = ""; 
    while ((sLine = proc.StandardOutput.ReadLine()) != null) 
    { 
     System.Console.WriteLine(sLine); 
    } 
    proc.WaitForExit(); //Jon Skeet was here! 
    errorCode = proc.ExitCode; 
    proc.Close(); 
} 
+0

Ich ging davon aus, dass der OP wollte, dass der Laichprozess weiterläuft - ich hatte den Aufruf von WaitForExit nicht bemerkt. Ich würde WaitForExit eher als Ihre while-Schleife verwenden - enge Schleifen sind keine gute Idee. –

+0

Ich versuche mich zu erinnern, ob es einen Grund gab, warum ich WaitForExit dort nicht benutzt habe. – crashmstr

+0

Betrachtet man meinen SVN-Verlauf, so lag das daran, dass ich es als "while (! Proc.HasExited) {/ * lies Zeug hier * /}" hatte, aber das bekam nicht den ganzen Text, und wenn ich mich bewegte Es außerhalb der Lese-Schleife, nicht daran gedacht, es zu einem WaitForExit zu ändern. – crashmstr

Verwandte Themen