Executing shell commands in C# - c#

I am trying to execute shell commands [which is supposed to be in cygwin's sh.exe] through a c# program.
Process proc = new Process();
ProcessStartInfo procStartInfo = new ProcessStartInfo(#"C:\cygwin64\bin\sh.exe", "history");
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
procStartInfo.RedirectStandardOutput = true;
procStartInfo.RedirectStandardError = true;
proc.StartInfo = procStartInfo;
proc.Start();
But i'm getting the following error instead of getting the list of commands
/usr/bin/sh: history: No such file or directory
Can you please let me know what i'm missing here?
Thanks

Related

c# OutputDataReceived does not work with curl

Following is the code to use OutputDataReceived to capture verbose information from curl.
There is no information can be captured this way. What is wrong?
var command = "curl.exe -vs -o test.html https:\\www.google.com";
var procStartInfo = new ProcessStartInfo("cmd", "/c " + command);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
var proc = new Process();
proc.EnableRaisingEvents = true;
proc.OutputDataReceived += (s, e) => {if(!string.IsNullOrEmpty(e.Data)) textBoxLog.AppendText(e.Data); };
proc.StartInfo = procStartInfo;
proc.Start();
proc.BeginOutputReadLine();
proc.WaitForExit();
proc.Close();
--output (or -o) writes the downloaded content into the given file (instead of writing it into stdout). The rest of cURL's output (progress meter, error messages, verbose mode etc.) is still written into stderr, which is shown in the terminal. https://en.wikipedia.org/wiki/Standard_streams
This means that you can only see the output of the HTML in C# with OutputDataReceived but not the output made by the verbose mode.
This code in a running console application, prints all the verbose info to the console without writing it manually with Console.WriteLine():
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = #"C:\Windows\System32\curl.exe";
startInfo.Arguments = #"https://vi.stackexchange.com/ -vs";
startInfo.RedirectStandardOutput = true;
process.StartInfo = startInfo;
process.Start();
You could save the output of the verbose mode to a txt file with curl through the help of a bat in this way:
curl https://vi.stackexchange.com/ -vs >curl-output.txt 2>&1
Or you could read the StandardError stream with ErrorDataReceived.
I would recommend to use the HttpWebRequest as shown on this question instead of using curl to do a request as a Process, unless you have a specific reason.
Thanks Malware Werewolf for pointing me to the right direction. The verbose info is stderr, not stdout. Following is corrected code to capture the verbose info.
var command = "curl.exe -vs -o test.html https:\\www.google.com";
var procStartInfo = new ProcessStartInfo("cmd", "/c " + command);
procStartInfo.RedirectStandardError = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
var proc = new Process();
proc.EnableRaisingEvents = true;
proc.ErrorDataReceived += (s, e) => {if(!string.IsNullOrEmpty(e.Data)) textBoxLog.AppendText(e.Data); };
proc.StartInfo = procStartInfo;
proc.Start();
proc.BeginErrorReadLine();
proc.WaitForExit();
proc.Close();

Run .exe from another app and enter values automatically

I want to run .exe file from another app, which is console app in .NET Core. When the app is open I want to write input to console from my code. Something like this:
var cmd = System.Diagnostics.Process.Start("myApp.exe");
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();
cmd.StandardInput.WriteLine("MyName"); // this should be entered in console as username
So I specify username from my code, instead of writing it to console manually. Code above is not working for me. Is there a way to do this?
enter username
You're first starting the Process and then you're manipulating the startup arguments. You need to start the process afterwards.
use something like this instead:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.UseShellExecute = false; //required to redirect standart input/output
// redirects on your choice
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.FileName = ...app path to execute...;
startInfo.Arguments = ...argumetns if required...;
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.StandardInput.WriteLine(...write whatever you want...);
source
You need redirect standard input. Create ProcessStartInfo structure, then start a process and after process started write to the process standart input
ProcessStartInfo processStartInfo = new ProcessStartInfo
{
FileName = pathToApplication,
RedirectStandardInput = true,
UseShellExecute = false
};
Process process = Process.Start(processStartInfo);
var writer = process.StandardInput;
writer.WriteLine("MyName");
Console.ReadLine();

C# - Launch application with arguments.

Hello I've to Launch the software CFast for a Parametric Analysis. To do this, I want to create a application in C# that runs the core CFast.exe. If I want run the software from cmd.exe and execute it on the file INPUTFILENAME.in I write in prompt:
CFast.exe INPUTFILENAME
In C# I wrote the following code:
Process firstProc = new Process();
firstProc.StartInfo.FileName = #"C:\Users\Alberto\Desktop\Simulazioni Cfast\D\C\N\A3B1\CFAST.exe";
firstProc.StartInfo.Arguments = #"INPUTFILENAME";
firstProc.EnableRaisingEvents = true;
firstProc.Start();
firstProc.WaitForExit();
With this code CFast run but doesn't analyze anything... Seems like don't accept the argument. Hint for this trouble ?
Solved. Mistake in the filename and in the syntax of the command
// setup cmd process
var command = #"CFAST.exe C:\Users\Alberto\Desktop\Simulazioni_Cfast\D\C\N\A3B1\A3B1";
ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd", "/c " + command);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.RedirectStandardError = true;
procStartInfo.CreateNoWindow = true;
// start process
Process proc = new Process();
proc.StartInfo = procStartInfo;
proc.Start();
proc.WaitForExit();
// read process output
string cmdError = proc.StandardError.ReadToEnd();
string cmdOutput = proc.StandardOutput.ReadToEnd();
where A3B1 is the name of the file .IN

How to run a bash command from Mono/MonoDevelop in Red Hat Linux?

I want to run the following bash command using C# and MonoDevelop and store the output to a variable.
./TestApp --H
My MonoDevelop Code:
Process proc = new Process();
proc.StartInfo.FileName = "/bin/bash";
proc.StartInfo.Arguments = "/usr/mono/TestApp --H";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardErrort = true;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
var output = proc.RedirectStandardOutput.ReadToEnd()
The above code is not working. The output variable is not getting the value as expected.
If I modify the above code by using a shell script, then its working.
Test.sh
#!/bin/bash
/usr/mono/TestApp --H;
Modified Mono Code:
proc.StartInfo.Arguments = "Test.sh";
Thank You
If /usr/mono/TestApp is not a shell script (for your question I guess it is not) this should work (you do not need bash to run programs):
Process proc = new Process();
proc.StartInfo.FileName = "/usr/mono/TestApp";
proc.StartInfo.Arguments = "--H";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
var output = proc.StandardOutput.ReadToEnd ();
Console.WriteLine("stdout: {0}", output);
By the way, be careful when using redirects. If pipes between TestApp process and Mono process get full, your application will not be able to finish (there is deadlock) Read the documentation for further information: RedirectStandardOutput

Hide console window from Process.Start C#

I am trying to create process on a remote machine using using System.Diagnostics.Process class.
I am able to create a process. But the problem is, creating a service is take a long time and console window is displayed.
Another annoying thing is the console window is displayed on top of my windows form and i cant do any other operations on that form.
I have set all properties like CreateNoWindow = true,
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
but still it shows the console window. even i have redirected output and errors to seperate stream but no luck.
Is there any other way to hide the Console window? Please help me out .
Here is the part of my code i used to execute sc command.
Process proc = new Process();
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc.StartInfo.FileName = "sc";
proc.StartInfo.Arguments = string.Format(#"\\SYS25 create MySvc binPath= C:\mysvc.exe");
proc.StartInfo.RedirectStandardError = false;
proc.StartInfo.RedirectStandardOutput = false;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.Start();
proc.WaitForExit();
I had a similar issue when attempting to start a process without showing the console window. I tested with several different combinations of property values until I found one that exhibited the behavior I wanted.
Here is a page detailing why the UseShellExecute property must be set to false.
http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.createnowindow.aspx
Under Remarks section on page:
If the UseShellExecute property is true or the UserName and
Password properties are not null, the CreateNoWindow property
value is ignored and a new window is created.
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = fullPath;
startInfo.Arguments = args;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
Process processTemp = new Process();
processTemp.StartInfo = startInfo;
processTemp.EnableRaisingEvents = true;
try
{
processTemp.Start();
}
catch (Exception e)
{
throw;
}
I've had bad luck with this answer, with the process (Wix light.exe) essentially going out to lunch and not coming home in time for dinner. However, the following worked well for me:
Process p = new Process();
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
// etc, then start process
This should work, try;
Add a System Reference.
using System.Diagnostics;
Then use this code to run your command in a hiden CMD Window.
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
cmd.StartInfo.Arguments = "Enter your command here";
cmd.Start();
This doesn't show the window:
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
cmd.StartInfo.CreateNoWindow = true;
...
cmd.Start();

Categories