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!
Related
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 have a working piece of code which executes commands using System.Diagnostic.Process. However, when I try to run nbtstat using the same code it does not return anything (neither is there an exception). When I run hostname (as an example) it returns the hostname.
string result = "";
//string commandToExec = "hostname";
string commandToExec = "nbtstat -A 10.10.10.5";
System.Diagnostics.ProcessStartInfo procStartInfo =
new System.Diagnostics.ProcessStartInfo("C:\\Windows\\System32\\cmd.exe", "/c " + commandToExec);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
result = proc.StandardOutput.ReadToEnd();
This command
nbtstat -A 10.10.10.5
works perfectly well from the command prompt. I am not able to understand the problem, neither find resources on the net which could help. If anyone can guide me in the right direction please?
You should call the nbtstat.exe program directly, there is no need to invoke CMD to call it. So use this line instead;
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo(#"c:\windows\sysnative\nbtstat.exe", "-A 10.10.10.5");
I also use Sysnative because of Windows64bit redirection. As exaplained in this post
I am currently trying to "convert" a bash script I wrote to C#.
This script starts a program in a shell and then executes a few commands in this shell and looks similar to this:
cd /$MYPATH
./executible -s << EOF
start_source_probe -hardware_name "USB" -device_name "#1: EP3C(10|5)"
write_source_data -instance_index 0 -value "11111"
write_source_data -instance_index 0 -value "10111"
write_source_data -instance_index 0 -value "00111"
exit
EOF
Now I would like to do the same using Visual Studio C#.
At the moment my attempt looks like this:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WorkingDirectory = "pathToExe\\";
startInfo.FileName= "executible.exe";
startInfo.Arguments= "-s";
//startInfo.UseShellExecute = false;
//startInfo.RedirectStandardInput = true;
Process proc = new Process();
proc.StartInfo = startInfo;
proc.Start();
//StreamWriter myStreamWriter = proc.StandardInput;
//Console.WriteLine("start_source_probe - hardware_name \"USB\" -device_name \"#1: EP3C(10|5)\"");
//Console.WriteLine("write_source_data -instance_index 0 -value \"11111\"");
proc.WaitForExit();
With the comments activated (so with the "//" in code) I manage to open the shell (-s stands for shell) but I wonder how I am able to execute commands in this shell additionally.
I managed to execute multiple commands with something like this (as long as I am not starting the shell because destination output differs I guess)
const string strCmdText = "/C command1&command2";
Process.Start("CMD.exe", strCmdText);
I would appreciate it if someone could tell me how to add the argument "-s" and execute commands in the started process.
I am not sure if i did understood your question, but you can create a batch file outside your c# code and call It from your c# code like the following :
System.Diagnostics.ProcessStartInfo ProcStartInfo = new System.Diagnostics.ProcessStartInfo("cmd");
ProcStartInfo.RedirectStandardOutput = true;
ProcStartInfo.UseShellExecute = false;
ProcStartInfo.CreateNoWindow = false;
ProcStartInfo.RedirectStandardError = true;
System.Diagnostics.Process MyProcess = new System.Diagnostics.Process();
ProcStartInfo.Arguments = "/c start /wait batch.bat ";
MyProcess.StartInfo = ProcStartInfo;
MyProcess.Start();
MyProcess.WaitForExit();
I added the /wait so your c# code is going to wait for your batch to finish, to pursuit the c# code execution
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.
I'm stuck on one thing i can't get solved. I have part of code, which is executed from command line like a charm. Works without any problem.
So, i will to try to call this command (same) out from C#.
That's the code i'm run from commandline.
java -Xincgc -Xmx1024m -cp
"%APPDATA%.minecraft\bin\minecraft.jar;%APPDATA%.minecraft\bin\lwjgl.jar;%APPDATA%.minecraft\bin\lwjgl_util.jar;%APPDATA%.minecraft\bin\jinput.jar"
-Djava.library.path="%APPDATA%.minecraft\bin\natives" net.minecraft.client.Minecraft "NAME"
The part i'm trying to get it in C# looks like:
proc.StartInfo.FileName = "java";
proc.StartInfo.Arguments = "-Xincgc -Xmx1024m -cp \"%APPDATA%\\.minecraft\\bin\\minecraft.jar;%APPDATA%\\.minecraft\\bin\\lwjgl.jar;%APPDATA%\\.minecraft\\bin\\lwjgl_util.jar;%APPDATA%\\.minecraft\\bin\\jinput.jar\" -Djava.library.path=\"%APPDATA%\\.minecraft\\bin\\natives\" net.minecraft.client.Minecraft \"NAME\"";
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = false;
proc.Start();
But, nothing happens at all. Is there something i'm doing wrong?
Thanks for any help!
Expand the environment variables in the Arguments using Environment.ExpandEnvironmentVariables.
string args = "-Xincgc -Xmx1024m -cp \"%APPDATA%\\.minecraft\\bin\\minecraft.jar;%APPDATA%\\.minecraft\\bin\\lwjgl.jar;%APPDATA%\\.minecraft\\bin\\lwjgl_util.jar;%APPDATA%\\.minecraft\\bin\\jinput.jar\" -Djava.library.path=\"%APPDATA%\\.minecraft\\bin\\natives\" net.minecraft.client.Minecraft \"NAME\"";
proc.StartInfo.Arguments = Environment.ExpandEnvironmentVariables(args);
BTW - you can use a verbatim string literal to make that argument string more readable.
#"-Xincgc -Xmx1024m -cp ""%APPDATA%\.minecraft\bin\minecraft.jar;%APPDATA%\.minecraft\bin\lwjgl.jar;%APPDATA%\.minecraft\bin\lwjgl_util.jar;%APPDATA%\.minecraft\bin\jinput.jar"" -Djava.library.path=""%APPDATA%\.minecraft\bin\natives"" net.minecraft.client.Minecraft ""NAME""";