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.
Related
The issue lies with the space between Test & Program. How do I get around this so Process.Start(Info); works as intended. I could change Test Program.exe to TestProgram.exe and this would work perfectly. Ive looked at similar questions but non seem to answer my question. Most mention String Replace or altering the string. I dont want to alter the string but regognise there is a space and process as normal.
Apoligies if this has been asked before but I cant seem to find it so please post the link if this has. Thanks
My code
private string program_name = "Test Program.exe";
ProcessStartInfo Info = new ProcessStartInfo();
Info.Arguments = "/C choice /C Y /N /D Y /T 0 & start " + program_name;
Info.WindowStyle = ProcessWindowStyle.Hidden;
Info.CreateNoWindow = true;
Info.FileName = "cmd.exe";
Process.Start(Info);
In your specific example - which seems a little odd, if you don't mind me saying - the program you are executing is part of the argument list and needs to be wrapped in double quotes like so:
Info.Arguments = "/C choice /C Y /N /D Y /T 0 & start \"" + program_name + "\"";
Or, just in case program_name is already quoted:
var quoted_name = $"\"{program_name.Trim('"')}\"";
Info.Arguments = "/C choice /C Y /N /D Y /T 0 & start " + quoted_name;
If that's really what you're using rather than a contrived example (which is perfectly fine as an example) then it would be simpler to just run the program directly rather than passing it as a commandline to cmd.exe, in which case you don't need the quotes at all:
ProcessStartInfo Info = new ProcessStartInfo();
Info.WindowStyle = ProcessWindowStyle.Hidden;
Info.CreateNoWindow = true;
Info.FileName = program_name; // or program_name.Trim('"')
Process.Start(Info);
Since you're hiding the console window anyway there doesn't seem much point explicitly invoking cmd.exe and having it wait around for the program to complete.
Try this:
Info.Arguments = "/C choice /C Y /N /D Y /T 0 & start \"" + program_name + "\"";
I am writing C# code to execute a powershell script.
The powershell script has two arguments:
subscriptionId of type string
resourceGroupNames of type string[]
Problem:
When running the C# program, the resourceGroupNames that is passed a is not being read by the powershell script.
Additionally, when running the C# program, powershell prompts me a message "Do you want to run this script?" Is there anyway to suppress this alert and have the powershell script to run automatically?
Here is my code:
Note that chefRepo is the path of the powershell script.
public void DoDeploymentRTM(string chefRepo, string subscriptionId, string[] resourceGroupNames)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = #"powershell.exe";
startInfo.Arguments = String.Format(#"& '{0}\AzurePowerShellScripts\azureVMStatusFetch.ps1' -subscriptionId {1} -resourceGroupNames {2}", chefRepo, subscriptionId, resourceGroupNames);
startInfo.Verb = "runas";
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
}
For passing an array as powershell argument you need to separate it's values by commas i.e. for integers you would pass e.g 1,2,3.
For string you need additional quotation marks (in case some items contain space) e.g.'first string','second string','third'.
In C# you would do this by
string.Join(',', resourceGroupNames.Select(x => "'" + x + "'"))
In order to make this approach work when calling by ProcessStartInfo you need to use powershell option -Command so that the array would be parsed correctly (see more details in question).
Concerning your second problem use powershell commandline option -ExecutionPolicy UnRestricted
Finally you just need to change your Arguments like this:
startInfo.Arguments = String.Format("-ExecutionPolicy UnRestricted -Command &\"'{0}\\AzurePowerShellScripts\\azureVMStatusFetch.ps1' - subscriptionId {1} -resourceGroupNames {2}\"", chefRepo, subscriptionId, string.Join(',', resourceGroupNames.Select(x => "'" + x + "'")));
or easier (for C# 7.0 or higher)
startInfo.Arguments = $"-ExecutionPolicy UnRestricted -Command &\"'{chefRepo}\\AzurePowerShellScripts\\azureVMStatusFetch.ps1' - subscriptionId {subscriptionId} -resourceGroupNames {string.Join(',', resourceGroupNames.Select(x => $"'{x}'"))}\"";
I am trying to execute a cmd command from .NET and using the find cmd command as a pipe. But the find cmd command takes the value in string but when i am creating my string variable instead of taking double quotes it is replacing it with /"".
My string variable is "/c sc QUERY ServiceName | find \"START\"" and instead of passing "/c sc QUERY ServiceName | find "START"" this to cmd shell it is passing "/c sc QUERY ServiceName | find \"START\"" and my find command is failing.
Below is my .NET code
string cmdstr = "/c sc QUERY ServiceName | find \"START\"";
Process prc = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = cmdstr;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
prc.StartInfo = startInfo;
prc.Start();
string result;
result = prc.StandardOutput.ReadToEnd();
prc.WaitForExit(10);
When i debug the code the cmdstr value does not contain double quotes but it contains the \"
Regarding your code:
It's fine and equivalent to manually open up cmd.exe and type sc QUERY ServiceName | find "START"
If i change ServiceName to W32Time and START to RUNNING, then I even get a non empty result (on my machine).
Regarding the debugger:
The debugger shows you the not evaluated version of the string (i.e. that what you actually type in the code).
If you want to see the string with evaluated escape-sequences, than you must use the "Text-Quickview"-Dialog (I don't know the exact title in English):
string cmdstr = string.Empty;
cmdstr = "/c sc QUERY ServiceName | find \"START\"";
cmdstr = cmdstr.Replace("\"", "");
cmdstr ="/c sc QUERY ServiceName | find START";
-Hope it works .
I've seen similar examples, but can't find something exactly like my problem.
I need to run a command like this from C#:
C:\FOLDER\folder with spaces\OTHER_FOLDER\executable.exe p1=hardCodedv1 p2=v2
I'm setting v2 at runtime, so I need to be able to modify the string in C# before calling Process.Start. Does anyone know how to handle this, since I have spaces between my parameters?
Even when you use the ProcessStartInfo Class, if you have to add spaces for arguments, then the above answers won't solve the problem. There's a simple solution. Just add quotes around arguments. That's all.
string fileName = #"D:\Company Accounts\Auditing Sep-2014 Reports.xlsx";
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.FileName = "Excel.exe";
startInfo.Arguments = "\"" + fileName + "\"";
System.Diagnostics.Process.Start(startInfo);
Here I've added escaped quotes around filename, and it works.
You can use the ProcessStartInfo class to separate your arguments, FileName, WorkingDirectory and arguments without worry for spaces
string fullPath = #"C:\FOLDER\folder with spaces\OTHER_FOLDER\executable.exe"
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = Path.GetFileName(fullPath);
psi.WorkingDirectory = Path.GetDirectoryName(fullPath);
psi.Arguments = "p1=hardCodedv1 p2=" + MakeParameter();
Process.Start(psi);
where MakeParameter is a function that returns the string to be used for the p2 parameter
Try this
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.FileName = "\"C:\\FOLDER\\folder with spaces\\OTHER_FOLDER\\executable.exe\"";
startInfo.Arguments = "p1=hardCodedv1 p2=v2";
Process.Start(startInfo);
After looking at the other solutions provided I ran into the issue where all my various arguments were bundled into one argument.
i.e. "-setting0=arg0 --subsetting0=arg1"
So I would propose the following:
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "\"" + Prefs.CaptureLocation.FullName + "\"";
psi.Arguments = String.Format("-setting0={0} --subsetting0={1}", "\"" + arg0 + "\"", "\"" + arg1+ "\"");
Process.Start(psi);
With the quotes around each argument, instead of around the entire set of arguments. And as pointed out by Red_Shadow this can all be done with the single line
Process.Start("\"" + filename + "\"", arguments here)
Very subtle caveat:
If I use ArgumentList, it only works when using it strictly trimmed (without leading or trailing spaces) and each string in it's own array place.
var psi = new ProcessStartInfo("cmd") {
ArgumentList = {
"--somepath",
"/root/subpath",
"--someid",
"12345",
}
};
If I try for example
"--somepath /root/subpath",
it doesn't work and I get errors from the cmd application.
Even
"--somepath ",
breaks the parser of the receiving program.
If the process you want to start is cmd /C
and the argument contains multiple spaces like C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe /N /T C:\users\someuser\AppData\Local\Temp\temp file with spaces.tmp Printer Name with Spaces maybe this answer will help you:
https://stackoverflow.com/a/6378038/20704455
In short: double quote
string arguments ="/C \"\"C:\\Program Files (x86)\\Adobe\\Acrobat Reader DC\\Reader\\AcroRd32.exe\" /N /T \"C:\\users\\someuser\\AppData\\Local\\Temp\\temp file with spaces.tmp\" \"Printer Name with Spaces\"\"";
ProcessStartInfo procStartInfo = new ProcessStartInfo("C:\\Windows\\sysnative\\cmd.exe",arguments);
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