Is it possible to run any Command Line based program or batch file and capturer (re-direct) the out put to a text box LIVE
the CL takes time and it produce text!
something like tracert.exe (it takes time and produce good amount of text).
actually I will work with tracert.exe and I like to capture the output live and show it in a text-box while it is running
EDIT: My problem is to have it LIVE I mean any new line or char the console produce will be sent/pulled to/by the textBox NOT until the program is done!
Simply I want to build is exactly like this http://www.codeproject.com/KB/threads/redir.aspx (check the demo) but in C#
here is my code:
private void button1_Click(object sender, EventArgs e)
{
Process pc = new Process();
pc.StartInfo.FileName = "tracert.exe";
pc.StartInfo.Arguments = "google.com";
pc.StartInfo.UseShellExecute = false;
pc.StartInfo.RedirectStandardOutput = true;
pc.StartInfo.CreateNoWindow = true;
pc.Start();
richTextBox1.Text = pc.StandardOutput.ReadToEnd();
pc.WaitForExit();
}
EDIT
with the your help (thanks a lot guys) and this link: http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k%28EHINVALIDOPERATION.WINFORMS.ILLEGALCROSSTHREADCALL%29;k%28TargetFrameworkMoniker-%22.NETFRAMEWORK%2cVERSION%3dV2.0%22%29;k%28DevLang-CSHARP%29&rd=true
I solve it with this code (do you think it is OK?):
namespace GUIforCL2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Process _cmd;
delegate void SetTextCallback(string text);
private void SetText(string text)
{
if (this.richTextBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.richTextBox1.Text += text + Environment.NewLine;
}
}
private void button1_Click(object sender, EventArgs e)
{
ProcessStartInfo cmdStartInfo = new ProcessStartInfo("tracert.exe");
cmdStartInfo.Arguments = "google.com";
cmdStartInfo.CreateNoWindow = true;
cmdStartInfo.RedirectStandardInput = true;
cmdStartInfo.RedirectStandardOutput = true;
cmdStartInfo.RedirectStandardError = true;
cmdStartInfo.UseShellExecute = false;
cmdStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
_cmd = new Process();
_cmd.StartInfo = cmdStartInfo;
if (_cmd.Start())
{
_cmd.OutputDataReceived += new DataReceivedEventHandler(_cmd_OutputDataReceived);
_cmd.ErrorDataReceived += new DataReceivedEventHandler(_cmd_ErrorDataReceived);
_cmd.Exited += new EventHandler(_cmd_Exited);
_cmd.BeginOutputReadLine();
_cmd.BeginErrorReadLine();
}
else
{
_cmd = null;
}
}
void _cmd_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
UpdateConsole(e.Data);
}
void _cmd_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
UpdateConsole(e.Data, Brushes.Red);
}
void _cmd_Exited(object sender, EventArgs e)
{
_cmd.OutputDataReceived -= new DataReceivedEventHandler(_cmd_OutputDataReceived);
_cmd.Exited -= new EventHandler(_cmd_Exited);
}
private void UpdateConsole(string text)
{
UpdateConsole(text, null);
}
private void UpdateConsole(string text, Brush color)
{
WriteLine(text, color);
}
private void WriteLine(string text, Brush color)
{
if (text != null)
{
SetText(text);
}
}
}
}
C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...
C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.
In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr. Stroustroupe.
C is more difficult to learn than JavaScript, but it's a valuable skill to have because most programming languages are actually implemented in C. This is because C is a “machine-level” language. So learning it will teach you how a computer works and will actually make learning new languages in the future easier.
When you create the Process
instance for tracert, you need to set the ProcessStartInfo.UseShellExecute
to false
and ProcessStartInfo.RedirectStandardOutput
to true
. This will allow you to use Process.StandardOutput
property to read the output.
You can use Process.BeginOutputReadLine
to start asynchronous reading and add an event handler to Process.OutputDataReceived
.
Update: Here's an example WPF program that does what you want.
MainWindow.xaml:
<Window x:Class="Console.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded" Closed="Window_Closed">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ScrollViewer Name="outputViewer" SizeChanged="ScrollViewer_SizeChanged" >
<TextBlock Name="output" />
</ScrollViewer>
<TextBox Grid.Row="1" Name="input" KeyDown="input_KeyDown" />
</Grid>
</Window>
MainWindow.cs:
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
namespace Console
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ProcessStartInfo cmdStartInfo = new ProcessStartInfo("cmd.exe");
cmdStartInfo.CreateNoWindow = true;
cmdStartInfo.RedirectStandardInput = true;
cmdStartInfo.RedirectStandardOutput = true;
cmdStartInfo.RedirectStandardError = true;
cmdStartInfo.UseShellExecute = false;
cmdStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
_cmd = new Process();
_cmd.StartInfo = cmdStartInfo;
if (_cmd.Start() == true)
{
_cmd.OutputDataReceived += new DataReceivedEventHandler(_cmd_OutputDataReceived);
_cmd.ErrorDataReceived += new DataReceivedEventHandler(_cmd_ErrorDataReceived);
_cmd.Exited += new EventHandler(_cmd_Exited);
_cmd.BeginOutputReadLine();
_cmd.BeginErrorReadLine();
}
else
{
_cmd = null;
}
}
private void Window_Closed(object sender, EventArgs e)
{
if ((_cmd != null) &&
(_cmd.HasExited != true))
{
_cmd.CancelErrorRead();
_cmd.CancelOutputRead();
_cmd.Close();
_cmd.WaitForExit();
}
}
void _cmd_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
UpdateConsole(e.Data);
}
void _cmd_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
UpdateConsole(e.Data, Brushes.Red);
}
void _cmd_Exited(object sender, EventArgs e)
{
_cmd.OutputDataReceived -= new DataReceivedEventHandler(_cmd_OutputDataReceived);
_cmd.Exited -= new EventHandler(_cmd_Exited);
}
private void ScrollViewer_SizeChanged(object sender, SizeChangedEventArgs e)
{
outputViewer.ScrollToBottom();
}
private void input_KeyDown(object sender, KeyEventArgs e)
{
switch (e.Key)
{
case Key.Enter:
_cmd.StandardInput.WriteLine(input.Text);
input.Text = "";
break;
case Key.Escape:
input.Text = "";
break;
}
}
private void UpdateConsole(string text)
{
UpdateConsole(text, null);
}
private void UpdateConsole(string text, Brush color)
{
if (!output.Dispatcher.CheckAccess())
{
output.Dispatcher.Invoke(
new Action(
() =>
{
WriteLine(text, color);
}
)
);
}
else
{
WriteLine(text, color);
}
}
private void WriteLine(string text, Brush color)
{
if (text != null)
{
Span line = new Span();
if (color != null)
{
line.Foreground = color;
}
foreach (string textLine in text.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
{
line.Inlines.Add(new Run(textLine));
}
line.Inlines.Add(new LineBreak());
output.Inlines.Add(line);
}
}
Process _cmd;
}
}
Yes - create the process using Process.Start(ProcessStartInfo)
having set RedirectStandardOutput
(and potentially RedirectStandardError
) to true and UseShellExecute
to false on the ProcessStartInfo
describing the process you want to start.
You can then either read directly from Process.StandardOutput
and Process.StandardError
(in separate threads, so that nothing blocks if the process fills its output buffer) or subscribe to the Process.OutputDataReceived
event and call Process.BeginOutputReadLine
(and the equivalent for standard error). MSDN has samples of all of this.
Note that in any case, you'll be receiving data on a different thread to the UI thread, so you'll want to use Control.Invoke
/ Control.BeginInvoke
to marshal back to the UI thread before
appending the text to the TextBox.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With