2009-04-24 6 views
5

Je génère un processus enfant qui s'exécute dans une fenêtre de console visible (c'est un fichier de commandes qui exécute MSBuild), et j'aimerais que la sortie soit générée par le processus affiché dans la fenêtre de la console visible, ainsi que capturer cette sortie afin que je puisse le traiter dans le code. J'ai lu plusieurs autres questions et la documentation MSDN traitant ProcessStartInfo.RedirectStandardOutput et autres, et je peux capturer la sortie du flux redirigé et traiter dans le code très bien:Capture la sortie standard et l'affiche toujours dans la fenêtre de la console

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

Le problème est que la la sortie n'est pas affichée dans la fenêtre de la console du processus enfant; Je reçois juste une fenêtre de console vide sur l'écran pendant que le processus est en cours, ce qui disparaît quand c'est fini. Je suppose que je pourrais cacher la fenêtre de processus enfant réelle, et afficher une seconde fenêtre que j'écrirais simplement la sortie comme il a été capturé, mais cela semble plus de travail que nécessaire. Est-il possible d'afficher la sortie dans la fenêtre de la console et de la capturer pour le traitement quand c'est fait?

Répondre

3

Une fois que vous avez redirigé la sortie standard, elle n'est plus dirigée vers la console. Pour écrire sur la console, vous devrez le faire manuellement.

Si vous souhaitez afficher la sortie lors de l'exécution du processus, au lieu d'effectuer un gros vidage à la fin, vous pouvez utiliser l'événement "OutputDataReceived" de la classe Process.

+0

Wow - Je ne l'avais pas vu OutputDataReceived avant. Soigné! –

+0

Cela semble répondre à la question de savoir si je peux ou non afficher la sortie dans la fenêtre de console appartenant au processus fils et redirigée vers le processus parent en même temps. Ma prochaine question serait, est-il possible de ne pas rediriger la sortie, et tout simplement capturer tout de la console lorsque le processus se termine? Ou, sinon, quelle est la meilleure façon de créer une fenêtre de console manuellement afin que je puisse écrire la sortie redirigée pendant que le processus s'exécute (en utilisant 'OutputDataReceived')? – mjl5007

+1

Jetez un oeil à http://msdn.microsoft.com/en-us/library/system.diagnostics.process.outputdatareceived.aspx. Il a un exemple (vous pouvez vouloir désactiver toutes les langues sauf C#) –

4

Voici ce que je l'ai utilisé, sans l'aide d'un thread séparé:


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

Je supposais que l'OP voulait que le processus de spawning continue à fonctionner - je n'avais pas remarqué l'appel à WaitForExit. J'utiliserais WaitForExit plutôt que votre boucle while - des boucles serrées ne sont pas une bonne idée. –

+0

J'essaie de me souvenir s'il y a une raison pour laquelle je n'ai pas utilisé WaitForExit. – crashmstr

+0

En regardant mon historique SVN, c'était parce que j'avais l'habitude de l'avoir comme "while (! Proc.HasExited) {/ * lire des trucs ici * /}", mais cela n'a pas tout le texte, et quand j'ai déménagé il en dehors de la boucle de lecture, n'a pas pensé à le changer en un WaitForExit. – crashmstr