Question

Je développe une application Windows Forms qui nécessite que j'appelle un programme distinct pour effectuer une tâche. Le programme est une application console et je dois rediriger la sortie standard de la console vers une zone de texte dans mon programme.

Je n’ai aucun problème à exécuter le programme à partir de mon application, mais je ne sais pas comment rediriger la sortie vers mon application. J'ai besoin de capturer la sortie pendant l'exécution du programme à l'aide d'événements.

Le programme de console n'est pas censé cesser de fonctionner tant que mon application n'est pas arrêtée et que le texte ne change pas constamment, à des intervalles aléatoires. Ce que je tente de faire, c’est simplement d’accrocher la sortie de la console pour déclencher un gestionnaire d’événements qui peut ensuite être utilisé pour mettre à jour la zone de texte.

J'utilise C # pour coder le programme et j'utilise le framework .NET pour le développement. L’application d’origine n’est pas un programme .NET.

EDIT: Voici un exemple de code de ce que j'essaie de faire. Dans ma dernière application, je remplacerai Console.WriteLine par du code pour mettre à jour la zone de texte. J'ai essayé de définir un point d'arrêt dans mon gestionnaire d'événements, qui n'est même pas atteint.

    void Method()
    {
        var p = new Process();
        var path = @"C:\ConsoleApp.exe";

        p.StartInfo.FileName = path;
        p.StartInfo.UseShellExecute = false;
        p.OutputDataReceived += p_OutputDataReceived;

        p.Start();
    }

    static void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        Console.WriteLine(">>> {0}", e.Data);
    }
Était-ce utile?

La solution

Cela fonctionne pour moi:

void RunWithRedirect(string cmdPath)
{
    var proc = new Process();
    proc.StartInfo.FileName = cmdPath;

    // set up output redirection
    proc.StartInfo.RedirectStandardOutput = true;
    proc.StartInfo.RedirectStandardError = true;    
    proc.EnableRaisingEvents = true;
    proc.StartInfo.CreateNoWindow = true;
    // see below for output handler
    proc.ErrorDataReceived += proc_DataReceived;
    proc.OutputDataReceived += proc_DataReceived;

    proc.Start();

    proc.BeginErrorReadLine();
    proc.BeginOutputReadLine();

    proc.WaitForExit();
}

void proc_DataReceived(object sender, DataReceivedEventArgs e)
{
    // output will be in string e.Data
}

Autres conseils

Vous pouvez utiliser le code suivant

        MemoryStream mem = new MemoryStream(1000);
        StreamWriter writer = new StreamWriter(mem);
        Console.SetOut(writer);

        Assembly assembly = Assembly.LoadFrom(@"C:\ConsoleApp.exe");
        assembly.EntryPoint.Invoke(null, null);
        writer.Close();

        string s = Encoding.Default.GetString(mem.ToArray());
        mem.Close();

J'ai ajouté un certain nombre de méthodes d'assistance à la plate-forme O2 (projet Open Source), qui vous permettent de créer facilement un script. 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 permettant d’afficher la sortie de la console du processus en cours (dans un contrôle existant ou une fenêtre contextuelle) est également utile. Voir ce billet de 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 informations sur la consommation de la console. sortie de nouveaux processus)

Merci à Marc Maxham pour sa réponse qui m'a permis de gagner du temps!

Comme le remarque Jon of All Trades, UseShellExecute doit être défini sur false pour rediriger les flux d'E / S, sinon l'appel Start () lève une InvalidOperationException. .

Voici ma modification du code où txtOut est une zone de texte en lecture seule WPF

void RunWithRedirect(string cmdargs)
{
    var proc = new Process()
    {
        StartInfo = new ProcessStartInfo("cmd.exe", "/k " + cmdargs)
        {
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            CreateNoWindow = true
        },
        EnableRaisingEvents = true
    };

    // see below for output handler
    proc.ErrorDataReceived += proc_DataReceived;
    proc.OutputDataReceived += proc_DataReceived;
    proc.Start();

    proc.BeginErrorReadLine();
    proc.BeginOutputReadLine();

    proc.WaitForExit();
}

void proc_DataReceived(object sender, DataReceivedEventArgs e)
{
    if (e.Data != null)
        Dispatcher.BeginInvoke(new Action( () => txtOut.Text += (Environment.NewLine + e.Data) ));
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top