web-dev-qa-db-fra.com

Capture de la sortie de la console à partir d'une application .NET (C #)

Comment appeler une application console depuis mon application .NET et capturer toutes les sorties générées dans la console?

(N'oubliez pas que je ne veux pas enregistrer les informations d'abord dans un fichier, puis les remettre à l'ordre du jour car j'aimerais beaucoup les recevoir en direct.)

119
Gripsoft

Ceci peut être facilement réalisé à l'aide de la propriété ProcessStartInfo.RedirectStandardOutput . Un exemple complet est contenu dans la documentation MSDN liée; le seul inconvénient est que vous devrez peut-être rediriger également le flux d'erreur standard pour afficher toutes les sorties de votre application.

Process compiler = new Process();
compiler.StartInfo.FileName = "csc.exe";
compiler.StartInfo.Arguments = "/r:System.dll /out:sample.exe stdstr.cs";
compiler.StartInfo.UseShellExecute = false;
compiler.StartInfo.RedirectStandardOutput = true;
compiler.Start();    

Console.WriteLine(compiler.StandardOutput.ReadToEnd());

compiler.WaitForExit();
155
mdb

C'est un peu l'amélioration par rapport à la réponse acceptée de @mdb. Plus précisément, nous capturons également les erreurs générées par le processus. En outre, nous capturons ces sorties par le biais d'événements, car ReadToEnd () ne fonctionne pas si vous souhaitez capturer une erreur les deux et une sortie normale. Il m'a fallu un certain temps pour que cela fonctionne, car cela nécessite également des appels à BeginxxxReadLine () après Start ().

using System.Diagnostics;

Process process = new Process();

void LaunchProcess()
{
    process.EnableRaisingEvents = true;
    process.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(process_OutputDataReceived);
    process.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(process_ErrorDataReceived);
    process.Exited += new System.EventHandler(process_Exited);

    process.StartInfo.FileName = "some.exe";
    process.StartInfo.Arguments = "param1 param2"
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.RedirectStandardError = true;
    process.StartInfo.RedirectStandardOutput = true;

    process.Start();
    process.BeginErrorReadLine();
    process.BeginOutputReadLine();          

    //below line is optional if we want a blocking call
    //process.WaitForExit();
}

void process_Exited(object sender, EventArgs e)
{
    Console.WriteLine(string.Format("process exited with code {0}\n", process.ExitCode.ToString()));
}

void process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
    Console.WriteLine(e.Data + "\n");
}

void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
    Console.WriteLine(e.Data + "\n");
}
28
Shital Shah

Utilisez ProcessInfo.RedirectStandardOutput pour rediriger la sortie lors de la création de votre processus de console.

Ensuite, vous pouvez utiliser Process.StandardOutput pour lire la sortie du programme.

Le second lien contient un exemple de code pour le faire.

13
Franci Penov

ConsoleAppLauncher est une bibliothèque open source spécialement conçue pour répondre à cette question. Il capture toutes les sorties générées dans la console et fournit une interface simple pour démarrer et fermer l'application de la console.

L'événement ConsoleOutput est déclenché chaque fois qu'une nouvelle ligne est écrite par la console dans la sortie standard/error. Les lignes sont en file d'attente et il est garanti qu'elles suivent l'ordre de sortie.

Également disponible en tant que paquet NuGet .

Exemple d'appel pour obtenir une sortie complète de la console:

// Run simplest Shell command and return its output.
public static string GetWindowsVersion()
{
    return ConsoleApp.Run("cmd", "/c ver").Output.Trim();
}

Échantillon avec rétroaction en direct:

// Run ping.exe asynchronously and return roundtrip times back to the caller in a callback
public static void PingUrl(string url, Action<string> replyHandler)
{
    var regex = new Regex("(time=|Average = )(?<time>.*?ms)", RegexOptions.Compiled);
    var app = new ConsoleApp("ping", url);
    app.ConsoleOutput += (o, args) =>
    {
        var match = regex.Match(args.Line);
        if (match.Success)
        {
            var roundtripTime = match.Groups["time"].Value;
            replyHandler(roundtripTime);
        }
    };
    app.Run();
}
7
SlavaGu

Ajoutée process.StartInfo.**CreateNoWindow** = true; et timeout.

private static void CaptureConsoleAppOutput(string exeName, string arguments, int timeoutMilliseconds, out int exitCode, out string output)
{
    using (Process process = new Process())
    {
        process.StartInfo.FileName = exeName;
        process.StartInfo.Arguments = arguments;
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.CreateNoWindow = true;
        process.Start();

        output = process.StandardOutput.ReadToEnd();

        bool exited = process.WaitForExit(timeoutMilliseconds);
        if (exited)
        {
            exitCode = process.ExitCode;
        }
        else
        {
            exitCode = -1;
        }
    }
}
2
Sergei Zinovyev

J'ai ajouté un certain nombre de méthodes d'assistance à O2 Platform (projet Open Source), ce qui vous permet de scripter facilement une interaction avec un autre processus via la sortie et l'entrée de la console (voir http://code.google.com/p/o2platform/source/browse/trunk/O2_Scripts/APIs/Windows/CmdExe/CmdExeAPI.cs )

L'API qui permet d'afficher la sortie de la console du processus en cours (dans une fenêtre de contrôle ou une fenêtre contextuelle existante) peut également s'avérer utile. Voir ce blog pour plus de détails: http://o2platform.wordpress.com/2011/11/26/api_consoleout-cs-inprocess-capture-of-the-console-output/ (ce blog contient également des détails sur la façon d'utiliser la sortie de la console des nouveaux processus)

2
Dinis Cruz

De PythonTR - Python Programcıları Derneği, e-kitap, örnek:

Process p = new Process();   // Create new object
p.StartInfo.UseShellExecute = false;  // Do not use Shell
p.StartInfo.RedirectStandardOutput = true;   // Redirect output
p.StartInfo.FileName = "c:\\python26\\python.exe";   // Path of our Python compiler
p.StartInfo.Arguments = "c:\\python26\\Hello_C_Python.py";   // Path of the .py to be executed
1
livetogogo