How To: Execute command line in C#, get STD OUT results
// 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();
Code is from MSDN.
How to execute a command and get its output
Executing a command getting its output
You can use this code to execute the above command:
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo = new System.Diagnostics.ProcessStartInfo()
{
UseShellExecute = false,
CreateNoWindow = true,
WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden,
FileName = "cmd.exe",
Arguments = "/C netstat -a -n |find \"5816\" |find \"ESTABLISHED\" /c",
RedirectStandardError = true,
RedirectStandardOutput = true
};
process.Start();
// Now read the value, parse to int and add 1 (from the original script)
int online = int.Parse(process.StandardOutput.ReadToEnd()) + 1;
process.WaitForExit();
This code starts the cmd.exe executable. Using the /C argument, you can give it the command you want to execute
A simple search in Stackoverflow gave me hundreds of questions that could help you.
Source: How To: Execute command line in C#, get STD OUT results, Run Command Prompt Commands
C# execute, wait, read command's output
The following snippet will work
public static string GetSystemInfo()
{
var command = "/c systeminfo";
var cmdsi = new ProcessStartInfo("cmd.exe");
cmdsi.Arguments = command;
cmdsi.RedirectStandardOutput = true;
cmdsi.UseShellExecute = false;
var cmd = Process.Start(cmdsi);
var output = cmd.StandardOutput.ReadToEnd();
cmd.WaitForExit();
return output;
}
You should set RedirectStandardOutput
to true
and read output before calling WaitForExit
, otherwise you can get a deadlock, per MSDN
The example avoids a deadlock condition by calling
p.StandardOutput.ReadToEnd
beforep.WaitForExit
. A deadlock condition
can result if the parent process callsp.WaitForExit
before
p.StandardOutput.ReadToEnd
and the child process writes enough text to
fill the redirected stream. The parent process would wait indefinitely
for the child process to exit.
/c
means terminating command line after execution
How do I get output from a command to appear in a control on a Form in real-time?
A brief description of what the code performs in this example:
The shell command (cmd.exe
) is run first, using start /WAIT
as parameter. More or less the same functionality as /k
: the console is started without any specific task, waiting to process a command when one is sent.
StandardOutput
, StandardError
and StandardInput
are all redirected, setting RedirectStandardOutput, RedirectStandardError and RedirectStandardInput properties of the ProcessStartInfo to true
.
The console Output stream, when written to, will raise the OutputDataReceived event; it's content can be read from the e.Data
member of the DataReceivedEventArgs.StandardError
will use its ErrorDataReceived event for the same purpose.
You could use a single event handler for both the events, but, after some testing, you might realize that is probably not a good idea. Having them separated avoids some weird overlapping and allows to easily tell apart errors from normal output (as a note, you can find programs that write to the error Stream instead of the output Stream).
StandardInput
can be redirected assigning it to a StreamWriter stream.
Each time a string is written to the stream, the console will interpret that input as a command to be executed.
Also, the Process is instructed to rise it's Exited event upon termination, setting its EnableRaisingEvents property to true
.
The Exited
event is raised when the Process is closed because an Exit
command is processed or calling the .Close() method (or, eventually, the .Kill() method, which should only be used when a Process is not responding anymore, for some reason).
Since we need to pass the console Output to some UI controls (RichTextBoxes
in this example) and the Process events are raised in ThreadPool Threads, we must synchronize this context with the UI's.
This can be done using the Process SynchronizingObject property, setting it to the Parent Form or using the Control.BeginInvoke method, that will execute a delegate function on the thread where the control's handle belongs.
Here, a MethodInvoker representing the delegate is used for this purpose.
The core function used to instantiate the Process and set its properties and event handlers:
using System;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
public partial class frmCmdInOut : Form
{
Process cmdProcess = null;
StreamWriter stdin = null;
public frmCmdInOut() => InitializeComponent();
private void MainForm_Load(object sender, EventArgs e)
{
rtbStdIn.Multiline = false;
rtbStdIn.SelectionIndent = 20;
}
private void btnStartProcess_Click(object sender, EventArgs e)
{
btnStartProcess.Enabled = false;
StartCmdProcess();
btnEndProcess.Enabled = true;
}
private void btnEndProcess_Click(object sender, EventArgs e)
{
if (stdin.BaseStream.CanWrite) {
stdin.WriteLine("exit");
}
btnEndProcess.Enabled = false;
btnStartProcess.Enabled = true;
cmdProcess?.Close();
}
private void rtbStdIn_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Enter) {
if (stdin == null) {
rtbStdErr.AppendText("Process not started" + Environment.NewLine);
return;
}
e.Handled = true;
if (stdin.BaseStream.CanWrite) {
stdin.Write(rtbStdIn.Text + Environment.NewLine);
stdin.WriteLine();
// To write to a Console app, just
// stdin.WriteLine(rtbStdIn.Text);
}
rtbStdIn.Clear();
}
}
private void StartCmdProcess()
{
var pStartInfo = new ProcessStartInfo {
FileName = "cmd.exe",
// Batch File Arguments = "/C START /b /WAIT somebatch.bat",
// Test: Arguments = "START /WAIT /K ipconfig /all",
Arguments = "START /WAIT",
WorkingDirectory = Environment.SystemDirectory,
// WorkingDirectory = Application.StartupPath,
RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true,
UseShellExecute = false,
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden,
};
cmdProcess = new Process {
StartInfo = pStartInfo,
EnableRaisingEvents = true,
// Test without and with this
// When SynchronizingObject is set, no need to BeginInvoke()
//SynchronizingObject = this
};
cmdProcess.Start();
cmdProcess.BeginErrorReadLine();
cmdProcess.BeginOutputReadLine();
stdin = cmdProcess.StandardInput;
// stdin.AutoFlush = true; <- already true
cmdProcess.OutputDataReceived += (s, evt) => {
if (evt.Data != null)
{
BeginInvoke(new MethodInvoker(() => {
rtbStdOut.AppendText(evt.Data + Environment.NewLine);
rtbStdOut.ScrollToCaret();
}));
}
};
cmdProcess.ErrorDataReceived += (s, evt) => {
if (evt.Data != null) {
BeginInvoke(new Action(() => {
rtbStdErr.AppendText(evt.Data + Environment.NewLine);
rtbStdErr.ScrollToCaret();
}));
}
};
cmdProcess.Exited += (s, evt) => {
stdin?.Dispose();
cmdProcess?.Dispose();
};
}
}
Since the StandardInput has been redirected to a StreamWriter:
stdin = cmdProcess.StandardInput;
we just write to the Stream to execute a command:
stdin.WriteLine(["Command Text"]);
The sample Form can be downloaded from PasteBin.
VB.Net version
Controls' names:rtbStdOut
-> RichTextBox (blue background), receives StdOutrtbStdErr
-> RichTextBox (in the middle), receives StdErrrtbStdIn
-> RichTextBox (at the bottom), writes to StdInbtnStartProcess
-> Button (on the right), starts the ProcessbtnEndProcess
-> Button (on the left), stops te Process
Download this Form from Google Drive
Imports System.Diagnostics
Imports System.IO
Public Class frmCmdInOut
Private cmdProcess As Process = Nothing
Private stdin As StreamWriter = Nothing
Protected Overrides Sub OnLoad(e As EventArgs)
MyBase.OnLoad(e)
rtbStdIn.Multiline = False
rtbStdIn.SelectionIndent = 20
End Sub
Private Sub btnStartProcess_Click(sender As Object, e As EventArgs) Handles btnStartProcess.Click
btnStartProcess.Enabled = False
StartCmdProcess(Me)
btnEndProcess.Enabled = True
End Sub
Private Sub btnEndProcess_Click(sender As Object, e As EventArgs) Handles btnEndProcess.Click
If stdin.BaseStream IsNot Nothing AndAlso stdin.BaseStream.CanWrite Then stdin.WriteLine("exit")
btnEndProcess.Enabled = False
btnStartProcess.Enabled = True
cmdProcess?.Close()
End Sub
Private Sub rtbStdIn_KeyPress(sender As Object, e As KeyPressEventArgs) Handles rtbStdIn.KeyPress
If e.KeyChar = ChrW(Keys.Enter) Then
If stdin Is Nothing Then
rtbStdErr.AppendText("Process not started" + Environment.NewLine)
Return
End If
e.Handled = True
If stdin.BaseStream.CanWrite Then
stdin.Write(rtbStdIn.Text + Environment.NewLine)
stdin.WriteLine() ' To write to a Console app, just stdin.WriteLine(rtbStdIn.Text);
End If
rtbStdIn.Clear()
End If
End Sub
Private Sub StartCmdProcess(synchObj As Control)
' Arguments = $"start /WAIT cscript.exe script.vbs /xpr",
' Batch File Arguments = "/C START /b /WAIT batchfile.bat",
' Test: Arguments = "START /WAIT /K ipconfig /all",
' start with /U
' StandardErrorEncoding = Encoding.Unicode,
' StandardOutputEncoding = Encoding.Unicode,
Dim pStartInfo = New ProcessStartInfo() With {
.FileName = "cmd.exe",
.Arguments = "START /WAIT",
.CreateNoWindow = True,
.RedirectStandardError = True,
.RedirectStandardInput = True,
.RedirectStandardOutput = True,
.UseShellExecute = False,
.WindowStyle = ProcessWindowStyle.Hidden,
.WorkingDirectory = Application.StartupPath
}
cmdProcess = New Process() With {
.EnableRaisingEvents = True,
.StartInfo = pStartInfo,
.SynchronizingObject = synchObj
}
cmdProcess.Start()
cmdProcess.BeginErrorReadLine()
cmdProcess.BeginOutputReadLine()
stdin = cmdProcess.StandardInput
AddHandler cmdProcess.OutputDataReceived,
Sub(s, evt)
If evt.Data IsNot Nothing Then
rtbStdOut.AppendText(evt.Data + Environment.NewLine)
rtbStdOut.ScrollToCaret()
End If
End Sub
AddHandler cmdProcess.ErrorDataReceived,
Sub(s, evt)
If evt.Data IsNot Nothing Then
rtbStdErr.AppendText(evt.Data + Environment.NewLine)
rtbStdErr.ScrollToCaret()
End If
End Sub
AddHandler cmdProcess.Exited,
Sub(s, evt)
stdin?.Dispose()
cmdProcess?.Dispose()
End Sub
End Sub
End Class
Running Command Line from C# without Window and Getting Output
This code gives me the correct ouput.
const string ipAddress = "127.0.0.1";
Process process = new Process
{
StartInfo =
{
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
FileName = "cmd.exe",
Arguments = "/C tracert -d " + ipAddress
}
};
process.Start();
process.WaitForExit();
if(process.HasExited)
{
string output = process.StandardOutput.ReadToEnd();
}
How to get the cmd command output in c# to a lable
instead of process.WaitForExit();
do something like this
The complete code for your function would look something like this
private void button1_Click(object sender, EventArgs e)
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Arguments = "/C ipconfig";
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardInput = true;
process.Start();
string q = "";
while(!process.HasExited)
{
q += process.StandardOutput.ReadToEnd();
}
label1.text = q;
MessageBox.Show(q);
}
Related Topics
Convert a Unicode String to an Escaped Ascii String
Entityframework - Contains Query of Composite Key
How to Cancel Task Await After a Timeout Period
Join/Where With Linq and Lambda
Benefits of Using the Conditional : (Ternary) Operator
How to Add a Timeout to Console.Readline()
Extension Method and Dynamic Object
Best Way to Keep Track and Iterate Through Tabs and Windows Using Windowhandles Using Selenium
Volatile Vs. Interlocked Vs. Lock
How to Handle Both a Single Item and an Array For the Same Property Using Json.Net
Case Insensitive 'Contains(String)'
Get Property Value from String Using Reflection
Cs0120: an Object Reference Is Required For the Nonstatic Field, Method, or Property 'Foo'
How and When to Use 'Async' and 'Await'
How to Deserialize Xml Document