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.

12voto

Jeff Mc Punkte 3473
 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();
 }

11voto

Tyrrrz Punkte 2145

Wenn es Ihnen nichts ausmacht, eine Abhängigkeit einzuführen, CliWrap kann dies für Sie vereinfachen:

using CliWrap;
using CliWrap.Buffered;

var result = await Cli.Wrap("target.exe")
   .WithArguments("arguments")
   .ExecuteBufferedAsync();

var stdout = result.StandardOutput;

7voto

Marc Gravell Punkte 970173

Sie müssen Folgendes verwenden ProcessStartInfo con RedirectStandardOutput aktiviert - dann können Sie den Ausgabestrom lesen. Sie könnten es einfacher finden, die Ausgabe mit ">" in eine Datei umzuleiten (über das Betriebssystem) und dann einfach die Datei zu lesen.

[Bearbeiten: wie bei Ray: +1]

7voto

Julian Punkte 770

Da die meisten Antworten hier nicht die using Statemant für IDisposable und einige andere Dinge, die meiner Meinung nach notwendig sein könnten, werde ich diese Antwort hinzufügen.

Für C# 8.0

// Start a process with the filename or path with filename e.g. "cmd". Please note the 
//using statemant
using myProcess.StartInfo.FileName = "cmd";
// add the arguments - Note add "/c" if you want to carry out tge  argument in cmd and  
// terminate
myProcess.StartInfo.Arguments = "/c dir";
// Allows to raise events
myProcess.EnableRaisingEvents = true;
//hosted by the application itself to not open a black cmd window
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.CreateNoWindow = true;
// Eventhander for data
myProcess.Exited += OnOutputDataRecived;
// Eventhandler for error
myProcess.ErrorDataReceived += OnErrorDataReceived;
// Eventhandler wich fires when exited
myProcess.Exited += OnExited;
// Starts the process
myProcess.Start();
//read the output before you wait for exit
myProcess.BeginOutputReadLine();
// wait for the finish - this will block (leave this out if you dont want to wait for 
// it, so it runs without blocking)
process.WaitForExit();

// Handle the dataevent
private void OnOutputDataRecived(object sender, DataReceivedEventArgs e)
{
    //do something with your data
    Trace.WriteLine(e.Data);
}

//Handle the error
private void OnErrorDataReceived(object sender, DataReceivedEventArgs e)
{        
    Trace.WriteLine(e.Data);
    //do something with your exception
    throw new Exception();
}    

// Handle Exited event and display process information.
private void OnExited(object sender, System.EventArgs e)
{
     Trace.WriteLine("Process exited");
}

6voto

TarmoPikaro Punkte 4208

Hier ein kleines Beispiel:

using System;
using System.Diagnostics;

class Program
{
    static void Main(string[] args)
    {
        var p = Process.Start(
            new ProcessStartInfo("git", "branch --show-current")
            {
                CreateNoWindow = true,
                UseShellExecute = false,
                RedirectStandardError = true,
                RedirectStandardOutput = true,
                WorkingDirectory = Environment.CurrentDirectory
            }
        );

        p.WaitForExit();
        string branchName =p.StandardOutput.ReadToEnd().TrimEnd();
        string errorInfoIfAny =p.StandardError.ReadToEnd().TrimEnd();

        if (errorInfoIfAny.Length != 0)
        {
            Console.WriteLine($"error: {errorInfoIfAny}");
        }
        else { 
            Console.WriteLine($"branch: {branchName}");
        }

    }
}

Ich glaube, das ist die kürzeste Form.

Bitte beachten Sie, dass die meisten Kommandozeilentools Standardausgabe und Standardfehler leicht verwechseln, manchmal ist es sinnvoll, diese in einem einzigen String zusammenzufassen.

Auch p.ExitCode könnte manchmal nützlich sein.

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