I am using the following command to run the bat file:
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = false;
p.StartInfo.FileName = "d:/my.bat";
p.Start();
p.WaitForExit(2000000);
p.Close();
p.Dispose();
My problem is that I need to wait until the above process get completed and close it as soon as it is possible.
Any suggestions?
You can replace p.WaitForExit(2000000) with p.WaitForExit(); in order to manage the case where the process takes longer than 2000000 milliseconds to run.
Link
Just use WaitForExit without any parameter like:
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = false;
p.StartInfo.FileName = "d:/my.bat";
p.Start();
p.WaitForExit();
p.Close();
p.Dispose();
It will wait until your process is done. See the documentation on MSDN for more info.
Alternatively, and especially if you want to give feedback to the user, you can do something like this:
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = false;
p.StartInfo.FileName = "d:/my.bat";
Console.Write("Running {0} ", p.StartInfo.FileName)
p.Start();
while (!p.HasExited)
{
Console.Write(".");
// wait one second
Thread.Sleep(1000);
}
Console.WriteLine(" done.");
p.Close();
p.Dispose();
Related
I'm trying to execute a command and wait for it to exit:
Process proc = new Process();
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.Arguments = "/c tasklist";
proc.Start();
proc.WaitForExit();
return;
However, tasklist command never exit if RedirectStandardOutput is set to true.
If I set RedirectStandardOutput to false or change the command to /c whoami, it exit almost immediately.
Any ideas?
You should read the output before calling WaitForExit(), this sample works fine:
Process proc = new Process();
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.Arguments = "/c tasklist";
proc.Start();
var output = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
Console.WriteLine(output);
return;
Without reading an output tasklist process waits until parent process read the output, according to remarks section of RedirectStandardOutput
A deadlock condition can result if the parent process calls
p.WaitForExit before p.StandardOutput.ReadToEnd and the child process
writes enough text to fill the redirected stream. The parent process
would wait indefinitely for the child process to exit. The child
process would wait indefinitely for the parent to read from the full
StandardOutput stream.
You can also do an asynchronous reading of process output (and limit a process wait for exit timeout), like this
Process proc = new Process();
StringBuilder output = new StringBuilder();
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.Arguments = "/c tasklist";
proc.OutputDataReceived += (s, e) =>
{
output.Append(e.Data).Append("\n");
};
proc.ErrorDataReceived += (s, e) =>
{
output.Append(e.Data).Append("\n");
};
proc.Start();
proc.BeginOutputReadLine();
proc.WaitForExit(100);
Console.WriteLine(output);
return;
Also, if you are going to redirect both streams (error and output), you have read at least one of them asynchronously, because of deadlocks again (MSDN link shows an example)
I currently have a portion of code that creates a new Process and executes it from the shell.
Process p = new Process();
...
p.Start();
p.WaitForExit();
This keeps the window open while the process is running, which is great. However, I also want to keep the window open after it finishes to view potential messages. Is there a way to do this?
It is easier to just capture the output from both the StandardOutput and the StandardError, store each output in a StringBuilder and use that result when the process is finished.
var sb = new StringBuilder();
Process p = new Process();
// redirect the output
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
// hookup the eventhandlers to capture the data that is received
p.OutputDataReceived += (sender, args) => sb.AppendLine(args.Data);
p.ErrorDataReceived += (sender, args) => sb.AppendLine(args.Data);
// direct start
p.StartInfo.UseShellExecute=false;
p.Start();
// start our event pumps
p.BeginOutputReadLine();
p.BeginErrorReadLine();
// until we are done
p.WaitForExit();
// do whatever you need with the content of sb.ToString();
You can add extra formatting in the sb.AppendLine statement to distinguish between standard and error output, like so: sb.AppendLine("ERR: {0}", args.Data);
This will open the shell, start your executable and keep the shell window open when the process ends
Process p = new Process();
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "CMD.EXE";
psi.Arguments = "/K yourmainprocess.exe";
p.StartInfo = psi;
p.Start();
p.WaitForExit();
or simply
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "CMD.EXE";
psi.Arguments = "/K yourmainprocess.exe";
Process p = Process.Start(psi);
if(p != null && !p.HasExited)
p.WaitForExit();
Be carefull espacially on switch /k, because in many examples is usually used /c.
CMD /K Run Command and then return to the CMD prompt.
CMD /C Run Command and then terminate
var p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/k yourmainprocess.exe";
p.Start();
p.WaitForExit();
Regarding: "Member Process.Start(ProcessStartInfo) cannot be accessed with an instance reference; qualify it with a type name instead"
This fixed the problem for me....
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "CMD.EXE";
psi.Arguments = "/K yourmainprocess.exe";
Process p = Process.Start(psi);
p.WaitForExit();
I have a process that I need hidden, I have tried the following lines of code to make it hidden:
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.CreateNoWindow = true;
The first line just simply does not make it non-visible and the second throws the following error:
"{"StandardOut has not been redirected or the process hasn't started yet."}
Also I need to have the output redirected to a richtextbox and the clipboard, so I cannot set redirectstandardoutput to false.
Here is my function for creating the process.
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = pingData;
p.Start();
p.WaitForExit();
string result = p.StandardOutput.ReadToEnd();
System.Windows.Forms.Clipboard.SetText(result);
if(p.HasExited)
{
richTextBox1.Text = result;
outPut = result;
MessageBox.Show( "Ping request has completed. \n Results have been copied to the clipboard.");
}
Thanks
Remove the following line:
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
Keep these two lines:
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
WindowStyle only applies to native Windows GUI applications.
I want to launch a .exe program using C# and read the values from the cmd generated from the .exe
The .exe launches successfully but I cannot read the values:
This is my code:
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = (#"D:\BSC\Thesis\Raphael_Thesis\smiledetector\bin\smiledetector.exe");
start.WorkingDirectory = #"D:\BSC\Thesis\Raphael_Thesis\smiledetector\bin\";
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
//Start the process
using (Process process = Process.Start(start))
{
// Read in all the text from the process with the StreamReader.
using (StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd();
textBox1.Text = result;
}
}
As Sam I Am has indicated, drop the using block for the StreamReader
using (Process process = Process.Start(start))
{
string result = process.StandardOutput.ReadToEnd();
textBox1.Text = result;
}
Keep in mind however your calling application will block until process completes and all the output can be read.
You need something like this:
private void btnStart_Click(object sender, EventArgs e)
{
p.StartInfo.FileName = #"D:\BSC\Thesis\Raphael_Thesis\smileDetector\vs2010\smiledetectorDebug";
p.StartInfo.WorkingDirectory = #"D:\BSC\Thesis\Raphael_Thesis\smileDetector\vs2010\";
p.StartInfo.RedirectStandardOutput = true;
p.EnableRaisingEvents = true;
p.StartInfo.UseShellExecute = false;
p.OutputDataReceived += new DataReceivedEventHandler(OutputHander);
p.Start();
p.BeginOutputReadLine();
p.WaitForExit();
}
where p is Process p = new Process();
void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
data.Add(Convert.ToInt32(e.Data));
}
where data is a List of int
I don't see any weird thing in your code, it should work fine. Taking a look at the doc, it gives a brief example of how to redirect it:
// Start the child process.
using(Process p = new Process())
{
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = #"D:\BSC\Thesis\Raphael_Thesis\smiledetector\bin\smiledetector.exe";
p.WorkingDirectory = #"D:\BSC\Thesis\Raphael_Thesis\smiledetector\bin\";
p.Start();
// Do not wait for the child process to exit before
// reading to the end of its redirected stream.
// p.WaitForExit();
// Read the output stream first and then wait.
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
}
source: Process.StandardOutput Property
I'm learning C# at the moment for a bit of fun and am trying to make a windows application that has a bit of a gui for running some python commands. Basically, I'm trying to teach myself the guts of running a process and sending commands to it, as well as receiving commands from it.
I have the following code at the moment:
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "C:/Python31/python.exe";
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
textBox1.Text = output;
Running python.exe from a command prompt gives some introductory text that I'd like to capture and send to a textbox in the windows form (textBox1). Basically, the goal is to have something that looks like the python console running from the windows app. When I don't set UseShellExecute to false, a console pops up and everything runs fine; however, when I set UseShellExecute to false in order to re-direct the input, all I get is that a console pops up very quickly and closes again.
What am I doing wrong here?
For some reason, you shouldn't use forward slashes when you start the process.
Compare (does not work):
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.FileName = "C:/windows/system32/cmd.exe";
p.StartInfo.Arguments = "/c dir" ;
p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
bool f = p.Start();
p.BeginOutputReadLine();
p.WaitForExit();
[...]
static void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
Console.WriteLine(e.Data);
}
to (works as expected):
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.FileName = #"C:\windows\system32\cmd.exe";
p.StartInfo.Arguments = "/c dir" ;
p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
bool f = p.Start();
p.BeginOutputReadLine();
p.WaitForExit();
[...]
static void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
Console.WriteLine(e.Data);
}
Python seems to be doing something weird. I wouldn't believe it until I tested it and then did some research. But all of these posts basically seem to have the same exact problem:
https://stackoverflow.com/questions/4106095/capturing-standard-output-from-django-using-c
Python & C#: Is IronPython absolutely necessary?
C# capturing python.exe output and displaying it in textbox
Certain Python commands aren't caught in Stdout