A method to execute cmd prompt command going wrong - c#

I have this method
private void _executeCommand(string commandStr, int timeout)
{
try
{
System.Diagnostics.ProcessStartInfo procStartInfo =
new System.Diagnostics.ProcessStartInfo("cmd", "/c " + commandStr);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
// Do not create the black window.
procStartInfo.CreateNoWindow = true;
// Now we create a process, assign its ProcessStartInfo and start it
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
Thread.Sleep(timeout);
}
catch (ExecutionEngineException e)
{
throw e;
}}
somehow, if I pass a string called myCmd, _executeCommand(myCmd, timeout), it does nothing. But if I pass the exact string value of myCmd, _executeCommand("copy //data//file \"C://Program Files/myApp\"", timeout), it was able to execute. Could anyone see what the problem is?

If you have a command that has its own arguments you want to execute using /c, you will need to enclose the entire command and its argument after /c in quotes. Further, if you're using a path that contains spaces as one of the arguments to your command you'll have to quote that too, i.e #"/c ""copy ""C:\My Folder\Ny File.txt"" ""C:\My Other Folder"""""
Also, If you have multiple commands that you want it to perform you will either have to put the commands in a batch file and execute that or enclose them in quotes and separate them with &&, i.e. #"/c ""cd \ && dir""".
Note that the doubling of quotes in my examples is how you escape quotes when using a string literal in C#. The # preceding the string tells the compiler to take the string literally and not to interpret \ characters as special.
Taking a look at my answer to Sending commands to cmd prompt in C# is probably a good idea too as it explains a lot about how this stuff works.

Related

C# Process with Python command (+path arguments)

I tried to pass a string representation of a python list that stores multiple paths to a Process in C# (later on, I would like to ast.literal_eval() the first argument):
ProcessStartInfo procStartInfo = new ProcessStartInfo("powershell", command);
procStartInfo.UseShellExecute = true;
procStartInfo.CreateNoWindow = true;
Process proc = new Process();
proc.StartInfo = procStartInfo;
proc.Start();
When using System.Console.Out.WriteLine(command) I get the following result:
python D:\'Box Sync'\Python\PdfMerge\PdfMerge.py -f "['C:\\Users\foo\Desktop\foo_bar.pdf', 'C:\\Users\foo\Desktop\bar_foo.pdf']" -mt "i" -op "C:\Users\foo\Desktop" -on "output"
I can copy that line into my PowerShell command line and when executed it works like a charm. However, trying to execute the script results in an error:
PdfMerge.py: error: unrecognized arguments: C:\\Users\foo\Desktop\bar_foo.pdf ]
I know that the string
"['C:\\\\Users\\foo\\Desktop\\foo_bar.pdf', 'C:\\\\Users\\foo\\Desktop\\bar_foo.pdf']"
works fine with the ast.literal_eval() so I want exactly that to be passed as an argument. I also tried to use verbatim string literals but I couldn't get any to work...
Am I missing something obvious?
Thanks for your help!

Copying data from textBox to cmd using startInfo.Arguments

I need to write the serial number (text) from a textBox to cmd command using startInfo.Arguments.
The main point is, all searches I did here pointed to replace the text in the beggining or in the end of the arguments.
But I need to insert the text from textBox to the middle of the argument, like this:
string input1 = textBox1.Text;
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.FileName = "CMD.exe";
startInfo.Arguments = "/c adb -s "textBox1.Text" shell dumpsys battery";
Any help will be appreciated. Thank you.
The content of the textbox has already been stored in the input1 variable.
Now we have multiple options to do this in C#:
startInfo.Arguments = String.Format(#"/c adb -s ""{0}"" shell dumpsys battery", input1);
(in the # string notation, double quotes are preserved in the resulting string by doubling them)
or with concatenation:
startInfo.Arguments = "/c adb -s \"" + input1 + "\" shell dumpsys battery";
(the backslash-escaped double quotes will preserve the double quote in the resulting string)
or, recently, we can use string interpolation:
startInfo.Arguments = $#"/c adb -s ""{input1}"" shell dumpsys battery";
Either way, consider to validate the value before you execute anything you obtained from a user, especially when it is started with administrative privileges.

Running CMD commands from C#

First of all, i searched a lot to avoid asking a duplicate question. If there is one, i will delete this question immediately.
All the solutions on the web are suggesting to use Process.StartInfo like this one
How To: Execute command line in C#, get STD OUT results
I dont want to run a batch file, or an .exe.
I just want to run some commands on cmd like
msg /server:192.168.2.1 console "foo" or ping 192.168.2.1
and return the result if there is one.
How can i do that ?
Those commands are still exe files, you just need to know where they are. For example:
c:\windows\system32\msg.exe /server:192.168.2.1 console "foo"
c:\windows\system32\ping.exe 192.168.2.1
The only proper way to do this is to use Process.Start. This is demonstrated adequately in this question, which is itself a duplicate of two others.
However, as DavidG says, the commands are all exe files and you can run them as such.
Apparently, i found an answer
while (true)
{
Console.WriteLine("Komut giriniz.");
string komut = Console.ReadLine();
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
//startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C" + komut;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
process.StartInfo = startInfo;
Console.WriteLine(process.Start());
string line = "";
while (!process.StandardOutput.EndOfStream)
{
line = line + System.Environment.NewLine + process.StandardOutput.ReadLine();
// do something with line
}
Console.WriteLine(line);
Console.ReadLine();
}
seems like if you can run cmd.exe with arguments including your command.
thanks for contributing.

Starting an executable and passing arguments

I have definitely done something like this before, but something is not working right and I'm not 100% sure what it is.
I have an executable executable.exe that takes a file, does some magic and outputs a second file somewhere else. So when I run this executable via CMD, all I need to do is pass "path1" and "path2". I put the paths in quotations because they may have spaces.
Anyway, so what I'm doing in my c# application is something like:
public void methodToRunExecutable()
{
var exePath = "\""+ "C:\\SomePathToAnExecutable" + "\"";
var firstFilePath = "C:\\PathToFirstFile\\NameOfFile.txt"
var secondFilePath= "C:\\PathToSecondFile\\NameOfFile.txt"
Process.Start(exePath, "\""firstFilePath + "\" \"" + secondFilePath+"\"")
}
However, I notice when I'm debugging is that the "\"" is actually showing up as \", like the backslash isn't escaping the quotation mark.
To be clear, when I run the CMD exe all I have to do is:
"C:\\PathToFirstFile\\NameOfFile.txt" "C:\\PathToSecondFile\\NameOfFile.txt"
and it works great. Any Ideas on what I'm doing wrong? Is it because the " is not being escaped?
Escaping is ugly and error prone. Use # and you won't need to escape:
var firstFilePath = #"C:\PathToFirstFile\NameOfFile.txt"
It might also be easier to use Process this way:
using (Process process = new Process())
{
process.StartInfo.FileName = exePath;
process.StartInfo.Arguments = ""; // args here
process.Start();
}

How to pass the arguments to a batch file?

I have requirement to run a set of *.sql files using batch file like this.
private void btn_Execute_Click(object sender, EventArgs e)
{
try {
//Creating A batch file to execute the scripts using SQLPLUS....
FileInfo fi5 = new FileInfo("c:/EMPSCRIPTS/execute.bat");
StreamWriter sw2 = fi5.CreateText();
sw2.WriteLine("#Echo Off \r \nsqlplus scotte/tiger#emp #\"c:/EMPSCRIPTS/RUNALL.sql\" \r \nEXIT ");
sw2.Close();
System.Diagnostics.Process proc; // Declare New Process
proc = System.Diagnostics.Process.Start(ConfigurationManager.AppSettings["BatFilePath"].ToString()); // run test.bat from command line.
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.Arguments = "/c" + ConfigurationManager.AppSettings["BatFilePath"].ToString();
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardInput = true;
proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
proc.Close();
}
catch (Exception ex) {
MessageBox.Show("Insertion Completed");
}
}
But I want to stop some files being executed unnecessarily. I found the option for passing the parameters. I want to give the parameters to the files staticly. Based on the users input that parameter has to execute. Could any one help me?
Thanks in Advance.
You're changing the values of StartInfo after the process has been started, which has no effect on the process. See the "Remarks" section here for more information.
Create a new instance of ProcessStartInfo, set it up with what you need, then pass it into the overload of Start that takes an instance of this type.
In addition, once you change your code around, you can probably skip writing the command line to the batch file. Your executable filename is sqlplus and your arguments are scotte/tiger#emp #\"c:/EMPSCRIPTS/RUNALL.sql\"
You're misusing Process.Start.
You need to create a new ProcessStartInfo object, set all of its properties, then pass it to Process.Start.
Modifying the StartInfo of an already-running process, as your code is doing, has no effect.

Categories

Resources