537 Stimmen

How To: Befehlszeile in C# ausführen, STD OUT Ergebnisse erhalten

Wie führe ich ein Befehlszeilenprogramm von C# aus und erhalte die STD OUT Ergebnisse zurück? Insbesondere möchte ich DIFF auf zwei Dateien ausführen, die programmgesteuert ausgewählt werden und die Ergebnisse in ein Textfeld schreiben.

595voto

Ray Jezek Punkte 6317
// 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();

Der Code stammt von MSDN .

168voto

Jeremy Punkte 42888

Hier ist ein kurzes Beispiel:

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

117voto

Peter Du Punkte 1264

Es gibt noch einen weiteren Parameter, den ich als nützlich empfunden habe und den ich verwende, um das Prozessfenster zu eliminieren

pProcess.StartInfo.CreateNoWindow = true;

Dies hilft, das schwarze Konsolenfenster vollständig vor dem Benutzer zu verbergen, falls Sie dies wünschen.

115voto

Lu55 Punkte 19425
// 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) +
        "'";
}

27voto

Cameron Punkte 2653

Die akzeptierte Antwort auf dieser Seite hat eine Schwachstelle, die in seltenen Situationen problematisch ist. Es gibt zwei Datei-Handles, in die Programme per Konvention schreiben: stdout und stderr. Wenn Sie nur ein einziges Dateihandle lesen, wie die Antwort von Ray, und das Programm, das Sie starten, genügend Ausgaben nach stderr schreibt, füllt es den Ausgabepuffer stderr und blockiert. Dann sind Ihre beiden Prozesse blockiert. Die Puffergröße kann 4K betragen. Bei kurzlebigen Programmen ist dies extrem selten, aber wenn Sie ein lang laufendes Programm haben, das wiederholt Ausgaben auf stderr macht, wird dies irgendwann passieren. Es ist schwierig, dieses Problem zu beheben und aufzuspüren.

Es gibt einige gute Möglichkeiten, damit umzugehen.

  1. Eine Möglichkeit besteht darin, cmd.exe anstelle Ihres Programms auszuführen und das Argument /c an cmd.exe zu verwenden, um Ihr Programm aufzurufen, sowie das Argument "2>&1" an cmd.exe, um es anzuweisen, stdout und stderr zusammenzuführen.

            var p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.Arguments = "/c mycmd.exe 2>&1";
  2. Eine andere Möglichkeit besteht darin, ein Programmiermodell zu verwenden, das beide Handles gleichzeitig liest.

            var p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.Arguments = @"/c dir \windows";
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardInput = false;
            p.OutputDataReceived += (a, b) => Console.WriteLine(b.Data);
            p.ErrorDataReceived += (a, b) => Console.WriteLine(b.Data);
            p.Start();
            p.BeginErrorReadLine();
            p.BeginOutputReadLine();
            p.WaitForExit();

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X