C# process.start, how do I know if the process ended? - c#

In C#, I can start a process with
process.start(program.exe);
How do I tell if the program is still running, or if it closed?

MSDN System.Diagnostics.Process
If you want to know right now, you can check the HasExited property.
var isRunning = !process.HasExited;
If it's a quick process, just wait for it.
process.WaitForExit();
If you're starting one up in the background, subscribe to the Exited event after setting EnableRaisingEvents to true.
process.EnableRaisingEvents = true;
process.Exited += (sender, e) => { /* do whatever */ };

Process p = new Process();
p.Exited += new EventHandler(p_Exited);
p.StartInfo.FileName = #"path to file";
p.EnableRaisingEvents = true;
p.Start();
void p_Exited(object sender, EventArgs e)
{
MessageBox.Show("Process exited");
}

Be sure you save the Process object if you use the static Process.Start() call (or create an instance with new), and then either check the HasExited property, or subscribe to the Exited event, depending on your needs.

Assign an event handler to the Exited event.
There is sample code in that MSDN link - I won't repeat it here.

Take a look at the MSDN documentation for the Process class.
In particular there is an event (Exited) you can listen to.

Related

How to open .exe files from C# one by one? [duplicate]

I've an application which does
Process.Start()
to start another application 'ABC'. I want to wait till that application ends (process dies) and continue my execution. How can I do it?
There may be multiple instances of the application 'ABC' running at the same time.
I think you just want this:
var process = Process.Start(...);
process.WaitForExit();
See the MSDN page for the method. It also has an overload where you can specify the timeout, so you're not potentially waiting forever.
Use Process.WaitForExit? Or subscribe to the Process.Exited event if you don't want to block? If that doesn't do what you want, please give us more information about your requirements.
I do the following in my application:
Process process = new Process();
process.StartInfo.FileName = executable;
process.StartInfo.Arguments = arguments;
process.StartInfo.ErrorDialog = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
process.Start();
process.WaitForExit(1000 * 60 * 5); // Wait up to five minutes.
There are a few extra features in there which you might find useful...
You could use wait for exit or you can catch the HasExited property and update your UI to keep the user "informed" (expectation management):
System.Diagnostics.Process process = System.Diagnostics.Process.Start("cmd.exe");
while (!process.HasExited)
{
//update UI
}
//done
I had a case where Process.HasExited didn't change after closing the window belonging to the process. So Process.WaitForExit() also didn't work. I had to monitor Process.Responding that went to false after closing the window like that:
while (!_process.HasExited && _process.Responding) {
Thread.Sleep(100);
}
...
Perhaps this helps someone.
Process.WaitForExit should be just what you're looking for I think.
Referring to the Microsoft example:
[https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.enableraisingevents?view=netframework-4.8]
Best would be to set:
myProcess.EnableRaisingEvents = true;
otherwiese the Code will be blocked.
Also no additional properties needed.
// Start a process and raise an event when done.
myProcess.StartInfo.FileName = fileName;
// Allows to raise event when the process is finished
myProcess.EnableRaisingEvents = true;
// Eventhandler wich fires when exited
myProcess.Exited += new EventHandler(myProcess_Exited);
// Starts the process
myProcess.Start();
// Handle Exited event and display process information.
private void myProcess_Exited(object sender, System.EventArgs e)
{
Console.WriteLine(
$"Exit time : {myProcess.ExitTime}\n" +
$"Exit code : {myProcess.ExitCode}\n" +
$"Elapsed time : {elapsedTime}");
}
Like Jon Skeet says, use the Process.Exited:
proc.StartInfo.FileName = exportPath + #"\" + fileExe;
proc.Exited += new EventHandler(myProcess_Exited);
proc.Start();
inProcess = true;
while (inProcess)
{
proc.Refresh();
System.Threading.Thread.Sleep(10);
if (proc.HasExited)
{
inProcess = false;
}
}
private void myProcess_Exited(object sender, System.EventArgs e)
{
inProcess = false;
Console.WriteLine("Exit time: {0}\r\n" +
"Exit code: {1}\r\n", proc.ExitTime, proc.ExitCode);
}
Try this:
string command = "...";
var process = Process.Start(command);
process.WaitForExit();

Why does the Process.Exited event fire two times?

I am writing an application in C# to download images using the Process class and wget.exe.
I want to handle the Process.Exited event without calling WaitForExit because calling WaitForExit hangs my UI. To work around this, I have tried many techniques like calling both Process.Start() and Process.WaitForExit() on another thread, using a BackgroundWorker etc. Still, my UI hangs at some level. So now I want simply handle the Process.Exited event without WaitForExit.
My code is:
bool processComplete = false;
Process process = new Process();
private void Start()
{
process.StartInfo.FileName = "path of wget";
process.StartInfo.Arguments = "arguments for downloading images";
process.EnableRaisingEvents = true;
process.Exited += new EventHandler(Process_Complete);
process.StartInfo.WindowStyle = ProcessWindowStyle.Hide;
process.Start();
}
private void Process_Complete(object sender, EventArgs e)
{
processComplete = true;
}
After starting the process, the Process.Exited event fires two times. First, while process is going on in between if some times downloading become slow(if images are more than 1000 etc ow at the starting only it fires process.exited event) and then after all images are downloaded,
I would expect the Process.Exited event to fire once. Why is it firing twice?
Faced the same issue.
I guess it's somehow related to accessing process members from different threads (in my case at least), 'cause from the log it's clear that handler is called from different threads.
Anyway, my solution was to unsubscribe from event in event handler:
bool processComplete = false;
Process process = new Process();
private void Start()
{
process.StartInfo.FileName = "path of wget";
process.StartInfo.Arguments = "arguments for downloading images";
process.EnableRaisingEvents = true;
process.Exited += Process_Complete;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hide;
process.Start();
}
private void Process_Complete(object sender, EventArgs e)
{
process.Exited -= Process_Complete;
processComplete = true;
}
I think alternative solution might be to synchronize access to process instance (using lock for example).

Is there any event to tell me a process is waiting for an input?

I am processing a Tex file by starting a Process like this one:
process p1 = new Process();
p1.StartInfo.FileName = "C:\\texlive\\2012\\bin\\win32\\pdflatex.exe";
p1.StartInfo.Arguments = FileName;
p1.consuleProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p1.consuleProcess.StartInfo.CreateNoWindow = true;
p1.consuleProcess.StartInfo.RedirectStandardOutput = true;
p1.consuleProcess.StartInfo.UseShellExecute = false;
p1.consuleProcess.StartInfo.RedirectStandardInput = true;
p1.Start();
p1.consuleProcess.BeginOutputReadLine();
p1.consuleProcess.OutputDataReceived += new DataReceivedEventHandler(p1_OutputDataReceived);
I display the output strings in a TextBox by handling OutputDataReceived event.
If there were an error in the Tex file, a line should be written in StandardInput. I think there is no event that can tell me, when the process is waiting for an input; So I thought, I can check OutputDataReceived event to see when the condition: e.Data == "?" is true. But, the problem is that the StandardInput needs an input, just before firing OutputDataReceived event with e.Data=="?"
So, what can I do to see when the process is waiting for an input?
thanks.
Not sure if this is what you mean but are you after something like
p1.WaitForInputIdle(NumberofMilisecondstoWait)
Update:
Maybe something like this
public void test()
{
p1.OutputDataReceived += new DataReceivedEventHandler(p1_OutputDataReceived);
}
void p1_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
throw new NotImplementedException();
}

How to start processes sequentially through code

I have to run 3 processes sequentially, one after other. The second process must start after first process' completion.
I work in C#. I have used Process.Start() method, Where it kicks on all at same time.
Can anyone help me.
One way of doing it adding a handler for the Exited event of the first process, and then starting the second process from there.
void StartProcessOne() {
Process p = Process.Start("foo", "bar");
p.Exited += (sender, e) => StartProcessTwo();
p.Start();
}
void StartProcessTwo() {
Process p = Process.Start("foo2", "bar2");
p.Exited += (sender, e) => StartProcessThree();
p.Start();
}
...
You can also use the WaitForExit() method, which waits for the process to end before continuing execution of your code. Note, however, this makes your own process stop execution until the other process terminates. This can leave you with an unresponsive user interface and such, which can be quite undesirable.(source)
Process.Start("yourprogram.exe").WaitForExit();
Process.Start("yournextprogram.exe").WaitForExit();
and so on...
You can accomplish this by responding to the Process.Exited event.
You should use this approach instead of WaitForExit() because the latter will block your program from responding to user input, etc...
private int n = 0;
private void StartAProcess()
{
Process process = new Process {
StartInfo = {FileName = "cmd.exe", Arguments = "pause"},
EnableRaisingEvents = true};
process.Exited += process_Exited;
process.Start();
n++;
}
void process_Exited(object sender, EventArgs e)
{
if (n < 3) StartAProcess();
}
try this code for each process
Process.WaitForExit()
http://msdn.microsoft.com/en-us/library/aa326953(v=VS.71).aspx
If you are using .NET 4 you could use the System.Threading.Tasks API. If your graph gets more complex you may get some mileage from http://pdag.codeplex.com (I must confess, this is my work).
You need to do a process.join() to wait for the first process to complete before submitting the next one. However, the bigger question is why you are using Process.Start() - for asynchronous tasks - when you actually want them to run synchronously? Just calling:
a();
b();
c();
will run them one after another.

Run code when current process terminates?

Is there a way to run a bit of code when the current process is getting terminated?
I want to log some stuff when a process terminates (either through external means - eg killing it - or quitting in the application itself).
We're talking about a Console application written in c#.
Thanks!
Have a look here: atexit, exit delegate in c#
I am not sure, but something similar would help
Process process = new Process();
.
.
process.Exited += new EventHandler(myProcess_Exited);
process.Start();
private void myProcess_Exited(object sender, System.EventArgs e)
{
eventHandled = true;
customAction(); // your logging stuff here
}
public void customAction()
{
//
}
have a look at: Process.Exited Event

Categories