493 votes

Comment faire : Exécuter une ligne de commande en C#, obtenir des résultats STD OUT

Comment exécuter un programme en ligne de commande à partir de C# et récupérer les résultats STD OUT ? Plus précisément, je veux exécuter DIFF sur deux fichiers qui sont sélectionnés par programme et écrire les résultats dans une zone de texte.

2 votes

Voir aussi stackoverflow.com/a/5367686/492 - il montre les événements pour les sorties et les erreurs.

0 votes

Apparenté (mais sans capturer STDOUT) : stackoverflow.com/questions/1469764

551voto

Ray Jezek Points 3016
// Start the child process.
 Process p = new Process();
 // Redirect the output stream of the child process.
 p.StartInfo.UseShellExecute = false;
 p.StartInfo.RedirectStandardOutput = true;
 p.StartInfo.FileName = "YOURBATCHFILE.bat";
 p.Start();
 // Do not wait for the child process to exit before
 // reading to the end of its redirected stream.
 // p.WaitForExit();
 // Read the output stream first and then wait.
 string output = p.StandardOutput.ReadToEnd();
 p.WaitForExit();

Le code provient de MSDN .

8 votes

Existe-t-il un moyen de faire cela sans fichier batch ? Le problème est que j'ai besoin d'envoyer des paramètres à la commande. J'utilise la commande xsd.exe <Assembly> /type:<ClassName>. Je dois donc pouvoir définir à la fois l'Assembly et le ClassName, puis exécuter la commande.

29 votes

Vous pouvez ajouter des arguments à votre appel par le biais de la fonction {YourProcessObject}.StartInfo.Arguments chaîne.

3 votes

Et si vous aimez les applications interactives et exécutantes ? Parce que vous ne pouvez pas utiliser ReadToEnd si vous le faites.

153voto

Jeremy Points 14078

Voici un échantillon rapide :

//Create process
System.Diagnostics.Process pProcess = new System.Diagnostics.Process();

//strCommand is path and file name of command to run
pProcess.StartInfo.FileName = strCommand;

//strCommandParameters are parameters to pass to program
pProcess.StartInfo.Arguments = strCommandParameters;

pProcess.StartInfo.UseShellExecute = false;

//Set output of program to be written to process output stream
pProcess.StartInfo.RedirectStandardOutput = true;   

//Optional
pProcess.StartInfo.WorkingDirectory = strWorkingDirectory;

//Start the process
pProcess.Start();

//Get program output
string strOutput = pProcess.StandardOutput.ReadToEnd();

//Wait for process to finish
pProcess.WaitForExit();

2 votes

+1 pour avoir montré comment ajouter des arguments à l'exécution d'un programme en ligne de commande (ce qui n'est pas le cas dans la réponse acceptée).

108voto

Peter Du Points 644

Il y a un autre paramètre que j'ai trouvé utile et que j'utilise pour éliminer la fenêtre de traitement.

pProcess.StartInfo.CreateNoWindow = true;

cela permet de cacher complètement la fenêtre noire de la console à l'utilisateur, si c'est ce que vous souhaitez.

3 votes

Cela m'a évité bien des maux de tête. Merci.

2 votes

Lorsque j'ai appelé "sc", j'ai dû également définir StartInfo.WindowStyle = ProcessWindowStyle.Hidden.

98voto

Lu55 Points 2339
// usage
const string ToolFileName = "example.exe";
string output = RunExternalExe(ToolFileName);

public string RunExternalExe(string filename, string arguments = null)
{
    var process = new Process();

    process.StartInfo.FileName = filename;
    if (!string.IsNullOrEmpty(arguments))
    {
        process.StartInfo.Arguments = arguments;
    }

    process.StartInfo.CreateNoWindow = true;
    process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    process.StartInfo.UseShellExecute = false;

    process.StartInfo.RedirectStandardError = true;
    process.StartInfo.RedirectStandardOutput = true;
    var stdOutput = new StringBuilder();
    process.OutputDataReceived += (sender, args) => stdOutput.AppendLine(args.Data); // Use AppendLine rather than Append since args.Data is one line of output, not including the newline character.

    string stdError = null;
    try
    {
        process.Start();
        process.BeginOutputReadLine();
        stdError = process.StandardError.ReadToEnd();
        process.WaitForExit();
    }
    catch (Exception e)
    {
        throw new Exception("OS error while executing " + Format(filename, arguments)+ ": " + e.Message, e);
    }

    if (process.ExitCode == 0)
    {
        return stdOutput.ToString();
    }
    else
    {
        var message = new StringBuilder();

        if (!string.IsNullOrEmpty(stdError))
        {
            message.AppendLine(stdError);
        }

        if (stdOutput.Length != 0)
        {
            message.AppendLine("Std output:");
            message.AppendLine(stdOutput.ToString());
        }

        throw new Exception(Format(filename, arguments) + " finished with exit code = " + process.ExitCode + ": " + message);
    }
}

private string Format(string filename, string arguments)
{
    return "'" + filename + 
        ((string.IsNullOrEmpty(arguments)) ? string.Empty : " " + arguments) +
        "'";
}

3 votes

Un exemple très complet, merci

2 votes

Il faudrait peut-être changer le gestionnaire OutputDataReceived en stdOut.AppendLine().

4 votes

À mon avis, il s'agit d'une solution beaucoup plus complète que la réponse acceptée. Je l'utilise maintenant, et je n'ai pas utilisé la réponse acceptée, mais celle-ci me semble vraiment insuffisante.

12voto

Jeff Mc Points 1741
 System.Diagnostics.ProcessStartInfo psi =
   new System.Diagnostics.ProcessStartInfo(@"program_to_call.exe");
 psi.RedirectStandardOutput = true;
 psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
 psi.UseShellExecute = false;
 System.Diagnostics.Process proc = System.Diagnostics.Process.Start(psi); ////
 System.IO.StreamReader myOutput = proc.StandardOutput;
 proc.WaitForExit(2000);
 if (proc.HasExited)
  {
      string output = myOutput.ReadToEnd();
 }

0 votes

Peut se bloquer lorsque le processus écrit beaucoup de données. Il est préférable de commencer à lire les données pendant que le processus est encore en cours d'exécution.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X