2009-04-24 7 views
5

Występuję proces potomny, który działa w widocznym oknie konsoli (jest to plik wsadowy, który uruchamia MSBuild), i chciałbym, aby wynik generowany przez proces wyświetlany w widocznym oknie konsoli, a także przechwytywanie tego wyniku, aby można było przetworzyć go w kodzie. Czytałem kilka innych pytań i dokumentacji MSDN czynienia z ProcessStartInfo.RedirectStandardOutput i tym podobne, i mogę przechwycić wyjście z przekierowanego strumienia i przetwarza je w kodzie dobrze:Przechwyć standardowe wyjście i nadal wyświetlaj je w oknie konsoli.

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(); 

Problem polega na tym, że dane wyjściowe nie są wyświetlane w oknie konsoli procesu potomnego; Po uruchomieniu procesu pojawia się puste okno konsoli, które znika po zakończeniu.

Przypuszczam, że mogłem ukryć rzeczywiste okno procesu potomnego i wyświetlić drugie okno, które po prostu zapisałbym dane wyjściowe w momencie przechwycenia, ale wydaje się, że wymaga to więcej pracy niż jest to konieczne. Czy istnieje sposób na wyświetlenie danych wyjściowych w oknie konsoli i nadal przechwytywanie ich do przetwarzania po zakończeniu?

Odpowiedz

3

Po przekierowaniu standardowego wyjścia nie jest już skierowany na konsolę. Aby napisać do konsoli, musisz to zrobić ręcznie.

Jeśli chcesz wyświetlić dane wyjściowe podczas wykonywania procesu, zamiast na 1 dużym zrzucie na końcu, możesz użyć zdarzenia "OutputDataReceived" klasy Proces.

+0

Wow - Nie widziałem OutputDataReceived wcześniej. Schludny! –

+0

Wydaje się, że to odpowiada na pytanie, czy mogę wyświetlać dane wyjściowe w oknie konsoli posiadanym przez proces potomny i przekierowane do procesu nadrzędnego w tym samym czasie. Moje następne pytanie brzmi: czy nie można przekierować danych wyjściowych i po prostu przechwycić wszystko z konsoli po zakończeniu procesu? Lub, jeśli nie, jaki jest najlepszy sposób ręcznego utworzenia okna konsoli, aby móc zapisać przekierowane wyjście do niego w trakcie wykonywania procesu (przy użyciu opcji "OutputDataReceived")? – mjl5007

+1

Zobacz http://msdn.microsoft.com/en-us/library/system.diagnostics.process.outputdatareceived.aspx. Ma przykład (możesz wyłączyć wszystkie języki, ale C#) –

4

Oto co Użyłem bez użycia oddzielnego wątku:


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

Przyjąłem, że OP chciał, aby proces odradzania nadal działał - nie zauważyłem połączenia z WaitForExit. Używałbym raczej WaitForExit niż pętli while - ciasne pętle nie są dobrym pomysłem. –

+0

Próbuję zapamiętać, czy był powód, dla którego nie użyłem WaitForExit tam. – crashmstr

+0

Patrząc na moją historię SVN, to dlatego, że zwykłem mieć ją jako "while (! Proc.HasExited) {/ * czytaj tutaj ... /}", ale to nie dostało całego tekstu, a kiedy się przeniosłem poza pętlą odczytu nie pomyślał o zmianie tego na WaitForExit. – crashmstr