C# Process removes quoted arguments - c#

The command I'm trying to execute is
"C:\Program Files (x86)\MyAPP\solr-6.2.0\bin\solr" start -f -c -z "10.195.42.93:2181,10.195.42.92:2181" -h 10.195.42.92
And this works just fine on the command Line.
I'm trying to execute this as C# process.
NOTE: Below code works fine if i remove the quotes surrounding IPList
var IPList="10.195.42.93:2181,10.195.42.92:2181";
var hostIP="10.195.42.92"
string command = #"/c ""C:\Program Files (x86)\MyApp\solr-6.2.0\bin\solr"" start -f -c -z """ + IPList + #""" -h " + hostIP;
Process process = new Process();
log.Info("Starting " + command);
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = command;
process.StartInfo = startInfo;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.OutputDataReceived += (s, e) => log.Info(e.Data);
process.ErrorDataReceived += (s, e) => log.Info(e.Data);
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
This throws error :
'C:\Program' is not recognized as an internal or external command,...
I have looked at the similar issue posted Here and tried the /s option but no heed.
What am i missing here ?

As the error says, it is trying to execute C:\Program which basically means something is wrong with the way you are escaping quotes. May be try to escape " using - \"

You're asking cmd.exe to run the command C:\Program Files (x86)\MyApp\solr-6.2.0\bin\solr. It will not run "C:\Program Files (x86)\MyApp\solr-6.2.0\bin\solr" because the quotes are consumed by the invocation of cmd.exe.
I do not know the proper way to fix this. You probably need to add escaped quotes somehow.

Enclosing the command with "(quotes) after /c solves the issue.
Example :
"/c ""c:\prog files\xyz\solr" start -c -z "blah,blah,blah" -h
IP "
Basically the command that is getting executed is
> cmd.exe /c "C:\Program Files (x86)\MyAPP\solr-6.2.0\bin\solr" start -f -c -z "10.195.42.93:2181,10.195.42.92:2181" -h 10.195.42.92
This command fails, and this has nothing to do with c# process api or .net.

Related

CLI Commands + Arguments are not executing correctly.

I`m working in the CLI commands in my Visual Studio C# application. This application does the interface with the Flash Programmer 2 (Texas Instruments Software to bootload the firmware in CC2560) using CLI ( Command-Line interface).
I checked some examples in StackOverflow, but I didn't have success to implement the solutions.
Steps of my application:
Select the serial port
Open the console
execute the srfprog.exe
execute the command line (srfprog -t soc(COM84,CC2650) -e -p -v -f c:\test.bin )
Check if the programming was a success
My file is located in: D:\Projects\Test_Fixture\Test_Fixture_Visual_Studio\SmartRF Tools\Flash Programmer 2\bin\srfprog.exe
When I execute this in my CMD (windows) the Prompt window shows
After this screen pop up I sent the commands to program the chip
srfprog -t soc(COM84,CC2650) -e -p -v -f c:\test.bin
This command will program and verify the code in the microcontroller CC2650 as show in the screenshot below:
The programming is perfect.
However when I run(Click the button - Load Firmware) my application open and close Shell window immediately. As shown in the figure below
My code is below:
private void button2_Click(object sender, EventArgs e)
{
System.Diagnostics.Process CC2650 = new System.Diagnostics.Process();
CC2650.StartInfo.FileName = #"D:\Projects\Test_Fixture\Test_Fixture_Visual_Studio\SmartRF Tools\Flash Programmer 2\bin\srfprog.exe";
CC2650.StartInfo.Arguments = "srfprog -t soc(COM84,CC2650) -e -p -v -f c:\test.bin"; //argument
CC2650.StartInfo.UseShellExecute = false;
CC2650.StartInfo.RedirectStandardOutput = true;
CC2650.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
CC2650.StartInfo.CreateNoWindow = false; //not diplay a windows
CC2650.Start();
string output = CC2650.StandardOutput.ReadToEnd(); //The output result
CC2650.WaitForExit();
}
In this test I`m using the fixed COM port. Later I will select the port.
Why my software is falling and doesn`t load the firmware?
Thank you for your attention and time.
Your code seems to be doubling up on srfprog by including it in the arguments. Filename defines the executable and Arguments should just be the stuff that comes after the Filename.
CC2650.StartInfo.Arguments = "-t soc(COM84,CC2650) -e -p -v -f c:\test.bin";
As mentioned before you don't need to pass the program name again in the arguments. To inspect what is happening please use code below. It will read the output and the errors in an async approach so we can analyse the output while the srfprog.exe is running.
I don't have any C# compiler here so I could not test this code before writing here, maybe you will have to change something to make it work. Please try it and let my know what will be printed in your Visual Studio output console.
// Add "using System.Diagnostics;"
private void button2_Click(object sender, EventArgs e)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = #"D:\Projects\Test_Fixture\Test_Fixture_Visual_Studio\SmartRF Tools\Flash Programmer 2\bin\srfprog.exe";
startInfo.Arguments = "-t soc(COM84,CC2650) -e -p -v -f c:\test.bin";
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
Process process = new Process();
process.StartInfo = startInfo;
process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
process.ErrorDataReceived += new DataReceivedEventHandler(OutputHandler);
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
}
static void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
Console.WriteLine(outLine.Data);
}

Psexec returns an access denied error in a c# code

I'm try trying to launch remote command via psexec tool, it is running successfully in command prompt. However in c#, I get the following output error:
Access is denied
.
here is my command:
psexec \servername -u xxxxxxx -p xxxxxxxxxx -h -w "E:\" cmd /C
"(dir)" ^> file.txt
here is my c# source:
ProcessStartInfo PSI = new ProcessStartInfo();
PSI.FileName = "cmd.exe";
PSI.RedirectStandardInput = true;
PSI.RedirectStandardOutput = true;
PSI.RedirectStandardError = true;
PSI.UseShellExecute = false;
PSI.CreateNoWindow = true;
PSI.WindowStyle = ProcessWindowStyle.Hidden;
PSI.Arguments = "psexec " + #"\\servername -u xxxxxx -p xxxxxxxxx -h -w "+"\"E:\\\\\" "+"cmd /C " +"\""+"(dir)"+ "\" " +"^> file.txt" ;
p.Start();
p.WaitForExit();
output = p.StandardOutput.ReadToEnd().ToString();
error = p.StandardError.ReadToEnd().ToString();
Sorry, I can't comment yet!
Reading your c# + psexec code, looks like it send
psexec \servername -u xxxxxxx -p xxxxxxxxxx -h -w "E:\\" cmd /C "(dir)" ^> file.txt to command prompt
Shouldn't it be "psexec " + #"\\servername -u xxxxxx -p xxxxxxxxx -h -w "+"\"E:\\\" "+"cmd /C " +"\""+"(dir)"+ "\" " +"^> file.txt"; to end with psexec \servername -u xxxxxxx -p xxxxxxxxxx -h -w "E:\" cmd /C "(dir)" ^> file.txt ?
To test I would suggest you to create an string which will receive those values and then show it, just to be sure is the right command being set.
Another thing is PSI.UseShellExecute = false;, I know some command codes must have this set false to work, but I don't know psexec, did you already also tried to set it to true ?
If the server that runs your code is under a domain, then you'll need to add the domain along with the user name.
Therefore, the -u flag would be -u your_domain_name\username.

execute asterisk cli command C#

I need a help with executing asterisk cli commands using C#. I'm able to open terminal window and start asterisk (see the code below), but dont know how to for example execute "sip show peers" command in CLI. Is there any possible way to do it?
using System;
using System.Diagnostics;
namespace runGnomeTerminal
{
class MainClass
{
public static void ExecuteCommand(string command)
{
Process proc = new System.Diagnostics.Process ();
proc.StartInfo.FileName = "/bin/bash";
proc.StartInfo.Arguments = "-c \" " + command + " \"";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start ();
while (!proc.StandardOutput.EndOfStream) {
Console.WriteLine (proc.StandardOutput.ReadLine ());
}
}
public static void Main (string[] args)
{
ExecuteCommand("gnome-terminal -x bash -ic 'cd $HOME; sudo asterisk -vvvvr; bash'");
}
}
}
All you triing to do is overkill. You just need ask asterisk for command, no need in bash or terminal.
Process proc = new System.Diagnostics.Process ();
proc.StartInfo.FileName = "/usr/sbin/asterisk";
proc.StartInfo.Arguments = "-rx \" " + command + " \"";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start ();
But please note, that command start NEW asterisk process, so not optimal. Best way is use asterisk AMI interface(which is just tcp connection, so much less resources use) and issue AMI action COMMAND.
There are number of already developed AMI interfaces, including C# one.
You can execute asterisk cli commands directly from bash, just -x to the asterisk command.
For example ExecuteCommand("gnome-terminal -x bash -ic 'cd $HOME; sudo asterisk -rx "sip show peers"; bash'");.

Cannot see the results of command line

Previously somebody has asked how to run a command line command in C# from visual studio and the beneath was the answer.
I tried the same intended to call a tool called cccc which can run on command line. But when I run the beneath code I do not get any results and nothing shows wrong.
Stating generally how can we run the same commands from C# as it was in command line and get the same results. Say I call a program (it could be any program that is able to run on command line, for instance, cccc, ccm, and so on) on command line and get some results. How to call the command line and give the arguments so it will call in its turn the cccc or whatever and do the same thing as it was without C#.
string strCmdText;
strCmdText = "/C d: cd D:\\Exercises\\npp52\\PowerEditor\\src && dir /s /b | cccc - --outdir=d:\\myfolder";
System.Diagnostics.Process.Start("CMD.exe", strCmdText);
Add 'pause' to the end of your command:
string strCmdText;
strCmdText = "/C d: cd D:\\Exercises\\npp52\\PowerEditor\\src && dir /s /b | cccc - --outdir=d:\\myfolder & pause";
System.Diagnostics.Process.Start("CMD.exe", strCmdText);
or redirect console standard output to a stream.
Here need more magic with OutputDataReceived handler
void Main()
{
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName="cmd.exe";
proc.StartInfo.Arguments = "/c ping 127.0.0.1";
proc.StartInfo.UseShellExecute = false;
proc.OutputDataReceived += new DataReceivedEventHandler(SortOutputHandler);
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
proc.BeginOutputReadLine();
proc.WaitForExit();
proc.Close();
}
private void SortOutputHandler(object sendingProcess,
DataReceivedEventArgs outLine)
{
if (!String.IsNullOrEmpty(outLine.Data))
{
// Do what You need with out
Console.WriteLine(outLine.Data);
}
}
Instead of trying to put everything inside a string you could take advantage of the ProcessStartInfo class to better define your arguments
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "CMD.EXE";
psi.WorkingDirectory = "D:\\Exercises\\npp52\\PowerEditor\\src ";
psi.Arguments = "/C dir /s /b | cccc - --outdir=d:\\myfolder"";
psi.WindowStyle = ProcessWindowStyle.Normal;
Process.Start(psi);
Also with the command window open you could see if there are syntax errors in your command
Another problem is that you are not using RedirectStandardOutput, so output is discarded. Take a look at this answer.

psexec.exe doesn't work when I create a Process from C#

Long story short...
This doesnt work:
Process p = new Process();
p.StartInfo.FileName = #"External\PsExec.exe";
string file = String.Concat(Path.Combine(Environment.CurrentDirectory,"temp"),#"\iisreset",DateTime.Now.ToString("ddMMyyyy-hhmmssss"),".txt");
p.StartInfo.Arguments = String.Format("-s -u {0}\\{1} -p {2} \\\\{3} iisreset > \"{4}\"", Domain,UserName, Password, machineIP, file);
p.StartInfo.CreateNoWindow = true;
p.Start();
p.WaitForExit();
I'm getting a RPC Unavailable message.
But when I access the command line in the program folder, then i run this: (with the correct parameters), exactly like I specified in the filename/arguments...
External\PsExec.exe -s -u [user] -p [password] \\[ip] iisreset > "[path]"
It works!
Do I have to specify anything else in the C# Process ? What could be possibly happening?
Thanks in advance!
EDIT: It works if I put cmd as the FileName and /c PsExec.exe before the arguments. The problem is this way it always show the window.
Instead of using p.startinfo.arguments use p.standardinput.writeline(command)
string PSPath = #"C:\PSTools\PsExec.exe";
fullcommand = PSPath + " -u " + userName + " -p " + password + " \\\\" + remoteMachine + " -h cmd.exe /c " + command + "";
Console.Clear();
//Console.WriteLine(fullcommand);
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.FileName = "cmd.exe";
//process.StartInfo.Arguments = fullcommand;
process.Start();
process.StandardInput.WriteLine(fullcommand);
process.StandardInput.Flush();
process.StandardInput.Close();
Console.WriteLine("*****Command*****");
Console.WriteLine(fullcommand);
Console.WriteLine("*****Output*****");
Console.WriteLine(process.StandardOutput.ReadToEnd());
Console.WriteLine("*****Error*****");
Console.WriteLine(process.StandardError.ReadToEnd());
Console.WriteLine("*****Exit*****");
process.WaitForExit();
Console.WriteLine("Again ?");
You cannot redirect standard output using the arguments the way you are doing. That's not how things actually work.
At the command line, your arguments end when the command interpreter sees the >, and it begins the process of redirecting standard output to the filename.
To accomplish this in C# you need to use the RedirectStandardOutput property of the StartInfo class, then read from the Process.StandardOutput stream and write to a file.
The MSDN documentation for RedirectStandardOutput has a short example you can use to get started.
iisreset [machinename] -
you don't need psexec

Categories

Resources