How to execute 2 different commands cmd on C# - c#

I was working on a project which needs to run two cmd commands on C#, I looked up on how to do it but nothing worked for me, and everyone was giving the solution to execute only one cmd command.
I would like to execute one command when the user clicks a button, then another one right after, without quitting the cmd, and if possible to hide the cmd window.
My goal would be to execute the 2 following commands in the cmd, to run a Run.bat file:
cd C:\users\user\documents\file
Run.bat
Thanks.

You can directly call "C:\users\user\documents\file\Run.bat" and set the working directory as well as the shell execute flag :
string path = #"C:\users\user\documents\file\";
var process = new System.Diagnostics.Process();
process.StartInfo.FileName = path + "Run.bat";
process.StartInfo.WorkingDirectory = path;
process.StartInfo.UseShellExecute = true;
process.Start();
//process.WaitForExit();

Related

C# command line execute commands belongs to another executable

Below is the code where I'm trying to run one command with argument. (Call Tectia SFTP client profile & upload file)
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.Arguments = $"/c sftpg3 {profile}";
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = true;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();
using (StreamWriter sw = cmd.StandardInput){
if (sw.BaseStream.CanWrite)
sw.WriteLine($"/c sput {filename} {output}");
}
After the process started, it logins into the into the SFTP and stucked. It won't input the next command as it deemed as another program.
Would like to ask how does it execute the next command after login? I tried Calling CMD with && concatenating and it won't works too. We can only use SFTP via command line as client requested.
Launch sftpg3 with the -B - option to read from standard input.
Launch sftpg3 with the -B <filename> option to read from a batch
file of commands.
More details of command line arguments is available in the documentation.
Also, I don't think you want to write /c the second time around. /c is just something passed to cmd.exe. On that note, why are you calling cmd.exe instead of the binary directly?

c# open cmd.exe process and Execute multiple commands

I would like to be able to open cmd and execute two commands from the window. First I would like to navigate to a particular directory where I can then run the second command from. Running a single command is pretty easy as this is all I have to do:
string path = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) + #"\Cisco Systems\VPN Client\";
Process process = new Process();
ProcessStartInfo processInfo = new ProcessStartInfo("cmd.exe", #"/c cd " + path );
process.StartInfo = processInfo;
process.Start();
However am not sure of the way to add the second argument so it runs after cmd runs the first command. Some research led me to this code snippet. Am unsure if this works since my aim is to start cisco vpn client from cmd and this seems not to start it. Here is the code:
string path = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) + #"\Cisco Systems\VPN Client\";
Process process = new Process();
ProcessStartInfo processInfo = new ProcessStartInfo("cmd.exe", #"/c cd " + path + "-t vpnclient connect user validuser pwd validpassword nocertpwd validconnectionentry ");
process.StartInfo = processInfo;
process.Start();
I once started the vpn client from cmd with the credentials just to make sure they were valid and it worked but I cant pull it off via C# programmatically.
Regards.
There three things you can do to achieve what you want. The easiest is to set the working directory of the process through ProcessStartInfo. This way you will only have to execute the command to start the VPN client.
The second option is redirecting the input and output of the process. (Also done through the ProcessStartInfo) This is something you want to do if you need to send more input to the process, or when you want to retrieve the output of the process you just started.
The third option is to combine the two commands with the & symbol. Using the & symbol makes cmd.exe execute the two commands sequentially (See here for an overview of the available symbols). Using this option will result in a command like this: /c cd path & vpnclient.
However because you just want to change the working directory of the process using the first option makes your code more readable. Because people reading your code do not need to know the & symbol in bash to understand what your code does. Changing the working directoy is done with the WorkingDirectory (MSDN) property of ProcessStartInfo (MSDN). See the following code:
var processInfo = new ProcessStartInfo("cmd.exe", #"/c vpnclient connect user validuser pwd validpassword nocertpwd validconnectionentry ");
processInfo.UseShellExecute = false;
processInfo.WorkingDirectory = path;
You can use & to execute next command or && to execute following command only if the previous one succeeded.
Examples:
dir /b & cls
and
taskkill /f /im explorer.exe && start explorer

Writing and executing multiple lines sequentially in an elevated command prompt using c#

Am a Newbie in C# and I have 3 commands(command2, command3 and command4) I need to execute in the elevated command prompt and I will also like to view the execution process as it happens. Currently, the problem is that the code below just opens the elevated command prompt and without executing the commands. I also seek better interpretations of the lines if wrong.
My code and Interpretation/Understanding of each line based on reviews of similar cases: ConsoleApp1
class Program
{
static void Main(string[] args)
{
string command2 = #"netsh wlan";
string command3 = #" set hostednetwork mode=true ssid=egghead key=beanhead keyusage=persistent";
string command4 = #" start hostednetwork";
string maincomm = command2.Replace(#"\", #"\\") + " " + command3.Replace(#"\", #"\\") ; //I merged commands 2 and 3
ProcessStartInfo newstartInfo = new ProcessStartInfo();
newstartInfo.FileName = "cmd"; //Intend to open cmd. without this the newProcess hits an error saying - Cannot run process without a filename.
newstartInfo.Verb = "runas"; //Opens cmd in elevated mode
newstartInfo.Arguments = maincomm; //I intend to pass in the merged commands.
newstartInfo.UseShellExecute = true; //
newstartInfo.CreateNoWindow = true; // I intend to see the cmd window
Process newProcess = new Process(); //
newProcess.StartInfo = newstartInfo; //Assigns my newstartInfo to the process object that will execute
newProcess.Start(); // Begin process and Execute newstartInfo
newProcess.StartInfo.Arguments = command4; //I intend to overwrite the initial command argument hereby passing the another command to execute.
newProcess.WaitForExit(); //
}
}
This is what I did to overcome the challenge and It gave me exactly what I wanted. I modified my code to use the System.IO to write directly to the elevated command prompt.
ProcessStartInfo newstartInfo = new ProcessStartInfo();
newstartInfo.FileName = "cmd";
newstartInfo.Verb = "runas";
newstartInfo.RedirectStandardInput = true;
newstartInfo.UseShellExecute = false; //The Process object must have the UseShellExecute property set to false in order to redirect IO streams.
Process newProcess = new Process();
newProcess.StartInfo = newstartInfo;
newProcess.Start();
StreamWriter write = newProcess.StandardInput ; //Using the Streamwriter to write to the elevated command prompt.
write.WriteLine(maincomm); //First command executes in elevated command prompt
write.WriteLine(command4); //Second command executes and Everything works fine
newProcess.WaitForExit();
Referrence: http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardinput(v=vs.110).aspx
http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo(v=vs.110).aspx
I think an understanding of some properties of the ProcessStartInfo might clear things.
The verb - Gets or sets the verb to use when opening the application or document specified by the FileName property.,
+The UseShellExecute - Gets or sets a value indicating whether to use the operating system shell to start the process.
+The FileName - Gets or sets the application or document to start MSDN Docs
When you use the operating system shell to start processes, you can start any document (which is any registered file type associated with an executable that has a default open action) and perform operations on the file, such as printing, by using the Process object. When UseShellExecute is false, you can start only executables by using the Process object Documentation from MSDN.
In my case, cmd is an executable. the verb property is some thing that answers the question "How should my I run my FileName(for executables e.g cmd or any application)?" for which I answered - "runas" i.e run as administrator. When the FileName is a document (e.g `someFile.txt), the verb answers the question "What should I do with the file for which answer(verb) could be -"Edit","print" etc. also?"
use true if the shell should be used when starting the process; false if the process should be created directly from the executable file. The default is true MSDN Docs - UserShellInfo.
Another thing worth noting is knowing what you are trying to achieve. In my case, I want to be able to run commands via an executable(cmd prompt) with the same process - i.e starting the cmd as a process I can keep track of.

How continuously communicate to Cmd?

I found how to open cmd in C#.
But I can use Inputstream only once.
Create Cmd Process
ProcessStartInfo CmdInfo = new ProcessStartInfo();
Process cmd = new Process();
CmdInfo.FileName = #"cmd";
CmdInfo.WindowStyle = ProcessWindowStyle.Hidden;
CmdInfo.CreateNoWindow = true;
CmdInfo.UseShellExecute = false;
CmdInfo.RedirectStandardInput = true;
CmdInfo.RedirectStandardOutput = true;
CmdInfo.RedirectStandardError = true;
cmd.EnableRaisingEvents = false;
cmd.StartInfo = CmdInfo;
cmd.Start();
Now we can use cmd.StandardInput and cmd.StandardOutput.
Use Cmd
// Use cmd 1
cmd.StandardInput.WriteLine("cd");
cmd.StandardInput.Close(); // if don't close, I can't get output
Console.WriteLine( cmd.StandardOutput.ReadToEnd() ); // Done!
// Use cmd 2
cmd.StandardInput.WriteLine("cd C:\"); // It will occure ObjectDisposedException
I want solve this problem.
I don't think you're going to get far with that approach. The code is a hint ProcessStart ! It's a new process! After you've started the process it's completely seperate to the one in which your code resides, the only way you would be able to communicate with this new process is via COM or remoting or some other inter application communication channel... MSMQ etc.
As far as I know the cmd (command prompt) offers none of these.
I think you'll want to study up on powershell...
Calling PowerShell From C#
http://www.codeproject.com/Articles/18229/How-to-run-PowerShell-scripts-from-C
etc etc
The command shell executable will not process commands from a redirected standard input until the input is closed.
You have three choices:
Create a new process for each command.
Pipeline all of the commands that you want to execute, then close the standard input handle.
Create a batch file containing all of the commands and then execute that.
If you choose to create a new process for each command, use cmd.exe's "/C" command line switch to execute the command rather than passing it through standard input.

Running cmd with C# and parameter

I have to compile a game like this
love "C:\testgame"
in the cmd. So I use this code, but it seems like the parameter is missinterpreted. Also, the console closes after a sec. But if I use Messagebox.Show I can see the command in the cmd is the same I manually use (and this works)
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.RedirectStandardInput =
true;
cmd.StartInfo.RedirectStandardOutput =
true;
cmd.StartInfo.CreateNoWindow = false;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();
cmd.StandardInput.Write(#"cd %ProgramFiles(x86)%\LOVE\");
MessageBox.Show("love \""+fldBrowDiag.SelectedPath.ToString()+#"\"+lsb_projects.SelectedItem.ToString()+"\"");
cmd.StandardInput.Close();
cmd.Close();
First, the "cd" command you issue will probably fail because you don't have quotes around the argument. (that program files env variable will have spaces in it.)
Second, instead of writing to stdin directly, maybe consider using the "/c" switch that will instruct cmd.exe to execute the specified commands directly. You can separate the commands with '&&'.
Try this to simplify things:
var process = Process.Start(
new ProcessStartInfo(#"C:\Program Files (x86)\LOVE\love.exe", #"C:\game") {
WorkingDirectory = #"C:\Program Files (x86)\LOVE" });
Why can't you just start cmd with the correct arguments to launch your process?
eg cmd /C love "c:\game" to close after finish or cmd /K love "c:\game to leave open after finish?

Categories