Run cmd command from inside my application - c#

I would like to make an application using C# form. Form has multiple label to show information and a button to click and show that information on that labels. All of the labels will show information which can be found using cmd. cmd will not show when program executes.
For Example:
If I need my motherboard information. It can be done using cmd commands "wmic baseboard get product,manufacturer"(without quotes). I would like to show same information on my C# form label by clicking on button. That need to be done hiding cmd windows.

You can use ProcessStartInfo and Process classes to run this application and redirect standard output to your own method.
Setting RedirectStandardOutput will make Process raise OutputDataReceived event which you can easily handle.
P.S. Pay attention to using Arguments to provide arguments.
var psi = new ProcessStartInfo(#"wmic");
psi.Arguments = #"baseboard get product,manufacturer";
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
string val = String.Empty;
var p = Process.Start(psi);
p.BeginOutputReadLine();
p.OutputDataReceived += delegate(object sender, DataReceivedEventArgs eventArgs)
{
val += eventArgs.Data + "\r\n";
};
p.WaitForExit();
MessageBox.Show(val); // Start parsing it here

Reference the code below against http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo%28v=vs.110%29.aspx and http://msdn.microsoft.com/en-us/library/system.diagnostics.process(v=vs.110).aspx
System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(yourCmd, yourCmdArguments);
psi.RedirectStandardOutput = false;
psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
psi.UseShellExecute = true;
System.Diagnostics.Process externalProcess;
externalProcess = System.Diagnostics.Process.Start(psi);
externalProcess.WaitForExit();

Related

Redirecting Continuous Output from a console to RichtextBox in C# Windows Form

I used this code to log the output from the exe in command prompt to RIchTextBox.
ProcessStartInfo psi = new ProcessStartInfo("adb.exe", "devices");
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.CreateNoWindow = true;
var proc = Process.Start(psi);
string s = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
richTextBox1.Text = s;
This is basically android command to get the list of connected devices. This works fines as it has just two lines.
If the output of the exe is continous data how it can be logged efficiently.
I replaced the command with adb.exe logcat but it hangs and nothing comes on the RichTextBox.
How can I log this coninous output on the RichetxtBox?
It's because you call ReadToEnd on the output stream; C# will keep reading it and reading it and only finish reading it when the stream closes. At that point your code carries on. Your task is more complex than you realize. To read incrementally you need something like:
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = Properties.Settings.Default.CommandLineFfmpegPath,
Arguments = string.Format(
Properties.Settings.Default.CommandLineFfmpegArgs,
OutputPath
),
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = true
};
var proc = System.Diagnostics.Process.Start(psi);
proc.OutputDataReceived += proc_OutputDataReceived;
proc.ErrorDataReceived += proc_ErrorDataReceived;
proc.BeginOutputReadLine();
And you need an event handler that will be called every time there is some data (but it will need to make sure it doesn't cause a cross thread violation), something like:
void proc_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (richTextbox1.InvokeRequired)
richTextbox1.Invoke((MethodInvoker) delegate {this.Text += e.Data;});
else
richTextbox1.Text += e.Data;
}
I'm not sure I'd use something as heavy as a richtextbox for this.. You probably aren't formatting (unless the console output is colored and youre gonna reinterpret the color codes) so a textbox would do fine.
Oh, and you probably don't want to jam your UI thread by WaitForExit either

C# Run console application from another app in a new console window

The second app is a console application and I want to see it's output window.
I know how to use Process.Start() but it doesn't show the console window for the app.
This is what I have tried:
Process.Start("MyApp.exe", "arg1 arg2");
So how to do it?
Perhapse this helps:
ProcessStartInfo info = new ProcessStartInfo(fileName, arg);
info.CreateNoWindow = false;
info.UseShellExecute = true;
Process processChild = Process.Start(info);
I figured it out. I have to run cmd command with /k argument (to keep the console window open) and then my whole command-line:
var command = "MyApp.exe arg1 arg2";
ProcessStartInfo processStartInfo = new ProcessStartInfo("cmd", "/k " + command);
processStartInfo.UseShellExecute = false;
Process process = new Process();
process.StartInfo = processStartInfo;
process.Start();
//In case you need the output. But you have to wait enough for the output
//string text = process.StandardOutput.ReadToEnd();

Stop process output from being displayed in project command window

I'm starting an exe via the Process class and I've noticed that the exe's output is being displayed inside my application's command window. *Note - when I start up the exe, I make sure a window is not opened - so, the only window that displays when my application is running is my main application, project.exe.
Is there a way to stop the exe's output from being displayed inside my project.exe command window? Here is my code:
Process process = new Process();
string exePath = System.IO.Path.Combine(workingDir, exeString);
process.StartInfo.FileName = exePath;
process.StartInfo.WorkingDirectory = workingDir;
process.StartInfo.Arguments = args;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += (s, e) => Logger.LogInfo(e.Data);
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
I've even tried setting RedirectStandardOutput to false with:
process.StartInfo.RedirectStandardOutput = false;
and the output is still placed in the command window.
This works when I tried locally on my box. Can you give it a try by replacing the exe path/name.
From MSDN doc's.
"When a Process writes text to its standard stream, that text is typically displayed on the console. By setting RedirectStandardOutput to true to redirect the StandardOutput stream, you can manipulate or suppress the output of a process. For example, you can filter the text, format it differently, or write the output to both the console and a designated log file"
https://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardoutput(v=vs.110).aspx
void Main()
{
Process process = new Process();
string exePath = System.IO.Path.Combine(#"C:\SourceCode\CS\DsSmokeTest\bin\Debug", "DsSmokeTest.exe");
process.StartInfo.FileName = exePath;
process.StartInfo.WorkingDirectory = #"C:\SourceCode\CS\DsSmokeTest\bin\Debug";
process.StartInfo.Arguments = string.Empty;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += (s, e) => Test(e.Data);
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
}
// Define other methods and classes here
public void Test(string input)
{
input.Dump();
}
just add the following line
process.StartInfo.UseShellExecute = true;

How to pass arguments to an already open terminal via System.Diagnostics.Process()

I have been messing around with triggering a bash script via C#. This all works fine when I first call the "open" command with arguments which in turn opens my .command script via Terminal.
Once the "open" command is used once Terminal or iTerm will remain open in the background, at which point calling the "open" command with arguments then has no further effect. I sadly have to manually quit the application to trigger my script again.
How can I pass arguments to an already open terminal application to restart my script without quitting?
I've searched online ad can't seem to work it out, it already took a good amount of time solve the opening code. Your help is much appreciated.
Here is the C# code I'm using to start the process:
var p = new System.Diagnostics.Process();
p.StartInfo.FileName = "open";
p.StartInfo.WorkingDirectory = installFolder;
p.StartInfo.Arguments = "/bin/bash --args \"open \"SomePath/Commands/myscript.command\"\"";
p.Start();
Thanks
EDIT:
Both answers were correct, this might help others:
ProcessStartInfo startInfo = new ProcessStartInfo("/bin/bash");
startInfo.WorkingDirectory = installFolder;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.StandardInput.WriteLine("echo helloworld");
process.StandardInput.WriteLine("exit"); // if no exit then WaitForExit will lockup your program
process.StandardInput.Flush();
string line = process.StandardOutput.ReadLine();
while (line != null)
{
Debug.Log("line:" + line);
line = process.StandardOutput.ReadLine();
}
process.WaitForExit();
//process.Kill(); // already killed my console told me with an error
You can try:
before calling p.Start():
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
// for the process to take commands from you, not from the keyboard
and after:
if (p != null)
{
p.StandardInput.WriteLine("echo helloworld");
p.StandardInput.WriteLine("executable.exe arg1 arg2");
}
(taken from here)
This is what you may be looking for :
Gets a stream used to write the input of the application.
MSDN | Process.StandardInput Property
// This could do the trick
process.StandardInput.WriteLine("..");

How to send commands to cmd in C#

I am coding a program in C# and I need to open cmd.exe, send my commands and get its answers.
I searched around and found some answers to take diagnostics.process in use.
Now, I have two problems:
When I get the output of process, the output is not shown on the cmd consoule itself.
I need to call g95 compiler on the system. When I call it from cmd manually, it is invoked and does well, but when I call it programmatically, I have the this error: "g95 is not recognized as an internal or external ..."
On the other hand, I only found how to send my commands to cmd.exe via arguments and process.standardInput.writeline(). Is there any more convenient method to use. I need to send commands when the cmd.exe is open.
I am sending a part of my code which may help:
System.Diagnostics.Process myProcess = new System.Diagnostics.Process();
myProcess.StartInfo = new System.Diagnostics.ProcessStartInfo("cmd.exe");
//myProcess.StartInfo.Arguments = "/c g95";
myProcess.StartInfo.UseShellExecute = true;
myProcess.StartInfo.RedirectStandardInput = true;
myProcess.StartInfo.RedirectStandardOutput = true;
myProcess.StartInfo.RedirectStandardError = true;
myProcess.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(myProcess_OutputDataReceived);
myProcess.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(myProcess_ErrorDataReceived);
myProcess.Start();
myProcess.BeginOutputReadLine();
myProcess.BeginErrorReadLine();
myProcess.StandardInput.WriteLine("g95 c:\\1_2.f -o c:\\1_2.exe");
You can specify the g95 directly and pass the desired command line parameters to it. You don't need to execute cmd first. The command may not be regognized because the settings from the user profile are not loaded. Try setting the property LoadUserProfile in StartInfo to true.
myProcess.StartInfo.LoadUserProfile = true;
This should also set the path variables correctly.
Your code would look something like this:
Process myProcess = new Process();
myProcess.StartInfo = new ProcessStartInfo("g95");
myProcess.StartInfo.Arguments = "c:\\1_2.f -o c:\\1_2.exe"
myProcess.StartInfo.UseShellExecute = true;
myProcess.StartInfo.LoadUserProfile = true;
myProcess.StartInfo.RedirectStandardInput = true;
myProcess.StartInfo.RedirectStandardOutput = true;
myProcess.StartInfo.RedirectStandardError = true;
myProcess.OutputDataReceived += myProcess_OutputDataReceived;
myProcess.ErrorDataReceived += myProcess_ErrorDataReceived;
myProcess.Start();
myProcess.BeginOutputReadLine();
myProcess.BeginErrorReadLine();
You are getting the error
"g95 is not recognized as an internal or external ..."
because you haven't added the path to g95.exe in your PATH environment variable. You will get similar result if you open up command prompt and type g95. Here is a link to G95 Windows FAQ page that explains it.

Categories