How to execute commands in Command Prompt using c# - c#

I want to execute these steps in CMD using c#
1 - CD C:\MySQL\MySQL Server 5.0\bin
2 - mysqldump -uroot -ppassword sample> d:\Test\222.sql
On manually doing this, i will get file named "222.sql"
I am using the below code to do it, but missing something.. Nothing Happens
public void CreateScript_AAR()
{
string commandLine = #"CD C:\MySQL\MySQL Server 5.0\bin\mysqldump -uroot -ppassword sample> d:\Test\222.sql""";
System.Diagnostics.ProcessStartInfo PSI = new System.Diagnostics.ProcessStartInfo("cmd.exe");
PSI.RedirectStandardInput = true;
PSI.RedirectStandardOutput = true;
PSI.RedirectStandardError = true;
PSI.UseShellExecute = false;
System.Diagnostics.Process p = System.Diagnostics.Process.Start(PSI);
System.IO.StreamWriter SW = p.StandardInput;
System.IO.StreamReader SR = p.StandardOutput;
SW.WriteLine(commandLine);
SW.Close();
}

You're executing both commands in 1 command, this is not valid syntax.
You don't even need to change the directory, so just remove the dirchange (CD) from your command string. Also, use quotes like Oded said.
string commandLine = #"""C:\MySQL\MySQL Server 5.0\bin\mysqldump"" -uroot -ppassword sample > d:\Test\222.sql";

You can also call MySqlDump.exe directly from your code without cmd.exe. Capture its output and write it to a file. Writing it in the correct encoding is important so that it restores correctly.
string binary = #"C:\MySQL\MySQL Server 5.0\bin\mysqldump.exe"
string arguments = #"-uroot -ppassword sample"
System.Diagnostics.ProcessStartInfo PSI = new System.Diagnostics.ProcessStartInfo(binary, arguments);
PSI.RedirectStandardInput = true;
PSI.RedirectStandardOutput = true;
PSI.RedirectStandardError = true;
PSI.UseShellExecute = false;
System.Diagnostics.Process p = System.Diagnostics.Process.Start(PSI);
Encoding encoding = p.StandardOutput.CurrentEncoding;
System.IO.StreamWriter SW = new StreamWriter(#"d:\Test\222.sql", false, encoding);
p.WaitOnExit();
string output = p.StandardOutput.ReadToEnd()
SW.Write(output)
SW.Close();

This is how I used it to meet my requirements.
public static void runResGen()
{
string ResGen = #"C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\ResGen.exe";
string outputPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\resxMerge";
DirectoryInfo dinfo = new DirectoryInfo(outputPath);
DirectoryInfo latestdir = dinfo.GetDirectories().OrderByDescending(f => f.CreationTime).FirstOrDefault();
string latestDirectory = latestdir.FullName.ToString();
string arguments = latestDirectory + "\\StringResources.resx /str:c#,,StringResources /publicClass";
ProcessStartInfo PSI = new ProcessStartInfo(ResGen, arguments);
PSI.RedirectStandardInput = true;
PSI.RedirectStandardOutput = true;
PSI.RedirectStandardError = true;
PSI.UseShellExecute = false;
PSI.CreateNoWindow = true;
System.Diagnostics.Process p = System.Diagnostics.Process.Start(PSI);
Encoding encoding = p.StandardOutput.CurrentEncoding;
p.Close();
}

Related

Execute cat command to overwrite file

I am trying to execute the cat command from my C# code, but I am running into problems.
So, this is just a very simple test, but I end up with the error:
Error: cat: '>': No such file or directory
Now... both source and target files actually exist.. and same result if target file does not exist.
If I open a console on my Raspberry Pi, it executes just fine. Any help is much appreciated.
My code:
var srcFile = "/home/pi/tm-satellite/Helpers/wpa_supplicant.conf";
var outFile = "/home/pi/tm-satellite/network-test.txt";
StringBuilder sb = new StringBuilder();
var info = new ProcessStartInfo();
info.FileName = "/bin/bash";
info.Arguments = $"-c 'cat {srcFile} > {outFile}'";
info.UseShellExecute = false;
info.CreateNoWindow = true;
info.RedirectStandardOutput = true;
info.RedirectStandardError = true;
var p = Process.Start(info);
//* Read the output (or the error)
sb.AppendLine($"Args: {info.Arguments}");
sb.AppendLine($"Output: {p!.StandardOutput.ReadToEnd()}");
sb.AppendLine($"Error: {p!.StandardError.ReadToEnd()}");
p!.WaitForExit();
return $"Overwrite system file {path}: {p.ExitCode}{Environment.NewLine}{sb}";
This is because you're passing the cat program the > argument.
> only makes sense in bash or sh process where it tells to the interpreter that stdout outputs should be dumped into file. It's not a valid argument for cat.
To get around this, invoke your cat process within your shell:
sh -c 'cat file1 > file2'
In C#
var srcFile = "/home/pi/tm-satellite/Helpers/wpa_supplicant.conf"
var outFile = "/home/pi/tm-satellite/network-test.txt"
var info = new ProcessStartInfo();
info.FileName = "sh";
info.Arguments = $"-c 'cat {srcFile} > {outFile}'";
Alternatively you can use C#'s File utilities to read the first file and write its contents into the second as it might be faster due to less I/O operations.
I've fixed my sample. Use double quotes instead of single quotes:
var srcFile = "~/bad";
var outFile = "~/good";
var pInfo = new ProcessStartInfo()
{
FileName = "sh",
Arguments = $"-c \"cat {srcFile} > {outFile}\""
};
var process = Process.Start(pInfo);
process.WaitForExit();

Call python scripts with many dependent libraries from C# code

We have a C# module that needs to pass XML as a string to a python module and get the process result from that python module (has complicated logic and many imported libraries). But somehow I got nothing returned after several tries, the following is my sample code. Also is that possible to use pyinstaller to package the python module into EXE and achieve same functionality?
public InquiryResponse ProcessXML(string xml)
{
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = #"C:\Python\python.exe";
psi.Arguments = string.Format(#"C:\myapp.py" {0}", xml);
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
var error = "";
var result = "";
using (var process = Process.Start(psi))
{
error = process.StandardError.ReadToEnd();
result = process.StandardOutput.ReadToEnd();
}
// Some other process
}

I am trying to call values from multiple textboxes and create a command line argument

So far I have this:
ProcessStartInfo psi = new ProcessStartInfo("cmd");
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.CreateNoWindow = true;
psi.RedirectStandardInput = true;
psi.WorkingDirectory = #"C:\";
var proc = Process.Start(psi);
string username = textBox1.Text;
string password = textBox2.Text; //not sure about these 3 lines is correct?
string urladdress = textBox7.Text;
proc.StandardInput
.WriteLine("program.exe URLHERE --username=****** --password=****** --list");
proc.StandardInput.WriteLine("exit");
string s = proc.StandardOutput.ReadToEnd();
richTextBox2.Text = s;
My problem is to get the it to create the command line like this:
program.exe https://website-iam-trying-to-reach.now --username=myusername --password=mypassword --list
Please note
You dont need to call CMD.exe. You can call program.exe directly.
You dont need to use StandardInput.WriteLine() to pass arguments.
You can pass arguments as follows:
string username = textBox1.Text;
string password = textBox2.Text;
string urladdress = textBox7.Text;
//Give full path here for program.exe
ProcessStartInfo psi = new ProcessStartInfo("program.exe");
//Pass arguments here
psi.Arguments = "program.exe " + urladdress + " --username=" + username + " --password=" + password + " --list";
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.CreateNoWindow = true;
psi.RedirectStandardInput = false;
psi.WorkingDirectory = #"C:\";
var proc = Process.Start(psi);
//You might want to use this line for the window to not exit immediately
proc.WaitForExit();
string s = proc.StandardOutput.ReadToEnd();
richTextBox2.Text = s;
proc.Close();
proc.Dispose();

Read from an external program/console

I have a problem, I need to execute a console program and I have to show the output information of that console on my program. I have a string variable called "result" that have to storage that information, but is always null and I don't know why. Can anyone help me? I put the code below:
Process p = new Process();
p.StartInfo.FileName = "python";
p.StartInfo.Arguments = #"C:\Users\xxx\xxx\xxx\xxx_\xxx yyy\zzz.py " + path;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.Start();
StreamReader sr = p.StandardOutput;
p.WaitForExit();
string result = sr.ReadToEnd();
sr.Close();
textBox1.Text = result;
On the console, I recieve 8382 JGK, for example, but my result variable is always "".
You could try something like this
StreamReader sr = p.StandardOutput;
p.WaitForExit();
char[] result = new char[p.Length]; //or sr.BaseStream.Length
sr.Read(result,0,(int)p.Length); // again or sr.BaseStream.Length
And see if result array contains anything.
I solve it! The problem was on the file's path. I have to put it on the same folder as the ".py" file and it works fine. I add the correct piece of code:
string python = #"C:\xxx\python.exe";
string myPythonApp = "program.py";
string x = #"file.jpg";
ProcessStartInfo myProcessStartInfo = new ProcessStartInfo(python);
myProcessStartInfo.UseShellExecute = false;
myProcessStartInfo.RedirectStandardOutput = true;
myProcessStartInfo.Arguments = myPythonApp + " " + x;
Process myProcess = new Process();
myProcess.StartInfo = myProcessStartInfo;
myProcess.StartInfo.CreateNoWindow = true;
myProcess.Start();
StreamReader myStreamReader = myProcess.StandardOutput;
string myString = myStreamReader.ReadLine();
myProcess.WaitForExit();
myProcess.Close();
textBox1.Text = myString;

Running exe with parameters doesn't work

var p = Process.Start(#"c:\PsTools\PsExec.exe", #"C:\Windows\System32\notepad.exe");
var err = p.StandardError.ReadToEnd();
var msg = p.StandardOutput.ReadToEnd();
lblStatusResponse.Text = "Err: " + err + "Msg: " + msg;
Why is my code not working?
I getting error:
System.InvalidOperationException: StandardError has not been redirected.
But when I add following:
p.StartInfo.RedirectStandardError = true;
var p = Process.Start(#"c:\PsTools\PsExec.exe", #"C:\Windows\System32\notepad.exe");)
it still gets the same error.
The main problem is that I wanna execute a exe with arguments, but I can't get it to work.
The following code generates a new p, this ignoring the settings you change in the previous instance:
var p = Process.Start(#"c:\PsTools\PsExec.exe", #"C:\Windows\System32\notepad.exe");)
So it doesn't really matter whether you initialize p like this
p.StartInfo.RedirectStandardError = true;
or not.
What you need to do
You need to create a ProcessStartInfo object, configure it and then pass it to Process.Start.
ProcessStartInfo p = new ProcessStartInfo(#"c:\PsTools\PsExec.exe", #"C:\Windows\System32\notepad.exe");
p.UseShellExecute = false;
p.RedirectStandardError = true;
p.RedirectStandardOutput = true;
Process proc = Process.Start(p);
var err = proc.StandardError.ReadToEnd();
var msg = proc.StandardOutput.ReadToEnd();
Taken from MSDN: https://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardoutput(v=vs.110).aspx
The StandardOutput stream has not been defined for redirection; ensure ProcessStartInfo.RedirectStandardOutput is set to true and ProcessStartInfo.UseShellExecute is set to false.
So remember to set those flags as instructed by MS.
Process proc = new Process();
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.Arguments = "/C " + command; //Enter your own command
proc.Start();
string output =proc.StandardOutput.ReadToEnd();
I know this is not the same code you have but this is was the only working code I have , that will run external command/process in C# , and return all of it output/errors to the application main window
public void Processing()
{
//Create and start the ffmpeg process
System.Diagnostics.ProcessStartInfo psi = new ProcessStartInfo("ffmpeg")
{ // this is fully command argument you can make it according to user input
Arguments = "-y -i '/mnt/Disk2/Video/Antina03.jpg' pp.mp4 ",
RedirectStandardOutput = true,
WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden,
UseShellExecute = false,
RedirectStandardError=true,
RedirectStandardInput=true
};
System.Diagnostics.Process ischk;
ischk = System.Diagnostics.Process.Start(psi);
ischk.WaitForExit();
////Create a streamreader to capture the output of ischk
System.IO.StreamReader ischkout = ischk.StandardOutput;
ischk.WaitForExit();
if (ischk.HasExited) // this condition very important to make asynchronous output
{
string output = ischkout.ReadToEnd();
out0 = output;
}
/// in case you got error message
System.IO.StreamReader iserror = ischk.StandardError;
ischk.WaitForExit();
if (ischk.HasExited)
{
string output = iserror.ReadToEnd();
out0 = output;
}
}
if you want to run this process just call the function Processing() BTW out0 are global variable so it can use out the function .
credit
I'm using MonoDevlop "C# devloping tool on Linux " and I get the output this way :-
public MainWindow() : base(Gtk.WindowType.Toplevel)
{
Build();
Processing();
textview2.Buffer.Text = out0;
}

Categories