Bagaimana cara menjalankan program baris perintah dari C # dan mendapatkan kembali hasil STD OUT? Secara khusus, saya ingin menjalankan DIFF pada dua file yang dipilih secara terprogram dan menulis hasilnya ke kotak teks.
Bagaimana cara menjalankan program baris perintah dari C # dan mendapatkan kembali hasil STD OUT? Secara khusus, saya ingin menjalankan DIFF pada dua file yang dipilih secara terprogram dan menulis hasilnya ke kotak teks.
Jawaban:
// 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();
Kode berasal dari MSDN .
{YourProcessObject}.StartInfo.Arguments
string.
p.StandardError
aliran. Ketika aliran menjadi penuh, tampaknya proses akan berhenti sampai data dikonsumsi, jadi saya harus membaca keduanya StandardError
dan StandardOutput
untuk memastikan bahwa tugas dijalankan dengan benar.
Berikut ini contoh cepat:
//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();
Ada satu parameter lain yang saya temukan berguna, yang saya gunakan untuk menghilangkan jendela proses
pProcess.StartInfo.CreateNoWindow = true;
ini membantu untuk menyembunyikan jendela konsol hitam dari pengguna sepenuhnya, jika itu yang Anda inginkan.
// 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) +
"'";
}
process.StartInfo.RedirectStandardError = true;
dan if (process.ExitCode == 0)
jawaban yang diterima tidak ada.
Jawaban yang diterima di halaman ini memiliki kelemahan yang merepotkan dalam situasi yang jarang terjadi. Ada dua file menangani program yang menulis dengan konvensi, stdout, dan stderr. Jika Anda baru saja membaca satu pegangan file seperti jawaban dari Ray, dan program yang Anda mulai tulis output yang cukup untuk stderr, itu akan mengisi buffer dan blok stderr output. Kemudian kedua proses Anda menemui jalan buntu. Ukuran buffer mungkin 4K. Ini sangat jarang terjadi pada program yang berumur pendek, tetapi jika Anda memiliki program yang berjalan lama yang berulang kali menghasilkan stderr, pada akhirnya akan terjadi. Ini sulit untuk di-debug dan dilacak.
Ada beberapa cara yang baik untuk mengatasi ini.
Salah satu caranya adalah dengan mengeksekusi cmd.exe daripada program Anda dan menggunakan argumen / c untuk cmd.exe untuk memanggil program Anda bersama dengan argumen "2> & 1" ke cmd.exe untuk memerintahkannya menggabungkan stdout dan stderr.
var p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/c mycmd.exe 2>&1";
Cara lain adalah dengan menggunakan model pemrograman yang membaca kedua pegangan pada saat yang sama.
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();
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();
}
Anda akan perlu menggunakan ProcessStartInfo
denganRedirectStandardOutput
diaktifkan - maka Anda dapat membaca aliran output. Anda mungkin merasa lebih mudah menggunakan ">" untuk mengarahkan ulang output ke file (melalui OS), dan kemudian cukup membaca file.
[edit: seperti yang dilakukan Ray: +1]
RedirectStandardOutput
sebenarnya.
Anda dapat meluncurkan program baris perintah apa pun menggunakan kelas Proses, dan mengatur properti StandardOutput dari instance Proses dengan pembaca aliran yang Anda buat (baik berdasarkan string atau lokasi memori). Setelah proses selesai, Anda dapat melakukan apa pun yang perlu dilakukan pada aliran itu.
Ini mungkin berguna bagi seseorang jika Anda mencoba untuk menanyakan cache ARP lokal pada PC / Server.
List<string[]> results = new List<string[]>();
using (Process p = new Process())
{
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.Arguments = "/c arp -a";
p.StartInfo.FileName = @"C:\Windows\System32\cmd.exe";
p.Start();
string line;
while ((line = p.StandardOutput.ReadLine()) != null)
{
if (line != "" && !line.Contains("Interface") && !line.Contains("Physical Address"))
{
var lineArr = line.Trim().Split(' ').Select(n => n).Where(n => !string.IsNullOrEmpty(n)).ToArray();
var arrResult = new string[]
{
lineArr[0],
lineArr[1],
lineArr[2]
};
results.Add(arrResult);
}
}
p.WaitForExit();
}
Perintah jalankan satu-liner:
new Process() { StartInfo = new ProcessStartInfo("echo", "Hello, World") }.Start();
Baca output dari perintah dalam jumlah terpendek dari kode yang dapat digunakan kembali:
var cliProcess = new Process() {
StartInfo = new ProcessStartInfo("echo", "Hello, World") {
UseShellExecute = false,
RedirectStandardOutput = true
}
};
cliProcess.Start();
string cliOut = cliProcess.StandardOutput.ReadToEnd();
cliProcess.WaitForExit();
cliProcess.Close();
Ada Kelas ProcessHelper di kode sumber terbuka PublicDomain yang mungkin menarik bagi Anda.
Jika Anda juga perlu menjalankan beberapa perintah di cmd.exe, Anda dapat melakukan hal berikut:
// 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 = "cmd.exe";
p.StartInfo.Arguments = "/C vol";
p.Start();
// Read the output stream first and then wait.
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Console.WriteLine(output);
Ini hanya mengembalikan output dari perintah itu sendiri:
Anda juga dapat menggunakan StandardInput
alih-alih StartInfo.Arguments
:
// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "cmd.exe";
p.Start();
// Read the output stream first and then wait.
p.StandardInput.WriteLine("vol");
p.StandardInput.WriteLine("exit");
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Console.WriteLine(output);
Hasilnya terlihat seperti ini:
Hanya untuk bersenang-senang, inilah solusi lengkap saya untuk mendapatkan output PYTHON - di bawah klik tombol - dengan pelaporan kesalahan. Cukup tambahkan tombol yang disebut "butPython" dan label yang disebut "llHello" ...
private void butPython(object sender, EventArgs e)
{
llHello.Text = "Calling Python...";
this.Refresh();
Tuple<String,String> python = GoPython(@"C:\Users\BLAH\Desktop\Code\Python\BLAH.py");
llHello.Text = python.Item1; // Show result.
if (python.Item2.Length > 0) MessageBox.Show("Sorry, there was an error:" + Environment.NewLine + python.Item2);
}
public Tuple<String,String> GoPython(string pythonFile, string moreArgs = "")
{
ProcessStartInfo PSI = new ProcessStartInfo();
PSI.FileName = "py.exe";
PSI.Arguments = string.Format("\"{0}\" {1}", pythonFile, moreArgs);
PSI.CreateNoWindow = true;
PSI.UseShellExecute = false;
PSI.RedirectStandardError = true;
PSI.RedirectStandardOutput = true;
using (Process process = Process.Start(PSI))
using (StreamReader reader = process.StandardOutput)
{
string stderr = process.StandardError.ReadToEnd(); // Error(s)!!
string result = reader.ReadToEnd(); // What we want.
return new Tuple<String,String> (result,stderr);
}
}
Karena sebagian besar jawaban di sini tidak menerapkan using
statemant untuk IDisposable
dan beberapa hal lain yang saya pikir bisa jadi perlu saya akan menambahkan jawaban ini.
Untuk 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");
}