0

The issue is how to track a process I start from my application.

I am doing a "launcher" and I would like to track when the program I launch is closed.

I checked these links, but I think it is not exactly the same I am trying because the processes I will launch are all of them javaw.exe and I need to treat them individually.

.Net Process monitor

How to detect a process start & end using c# in windows?

This is how the code looks now:

{
    Process proc = new Process();
    proc.Exited += EclipseInstanceClosed;
    proc.Disposed += EclipseInstanceDisposed;
    // this property is a *.exe path: 'C:\eclipse\eclipseV4.4.1\eclipse.exe' for example
    proc.StartInfo.FileName = SelectedEclipseInstance.Exec;
    proc.StartInfo.UseShellExecute = true;

    proc.Start();
}

...

void EclipseInstanceClosed(object sender, EventArgs e)
{
    MessageBox.Show("Eclipse was closed!");
}

void EclipseInstanceDisposed(object sender, EventArgs e)
{
    MessageBox.Show("Eclipse was disposed!");
}

But these events are not raised when I close the program.

Any idea about it?

Update:

I also tried this solution(why Process's Exited method not being called? ) with proc.EnableRaisingEvents = true; but with no success

Update II:

I modified the code so the process is started within a Task. In this case the events are raised. What is the reason?

LaunchEclipseProcess();

...

private async void LaunchEclipseProcess()
{
    await Task.Run(() =>
    {
        Process proc = new Process();
        proc.EnableRaisingEvents = true;
        proc.StartInfo.UseShellExecute = true;

        proc.Exited += EclipseInstanceClosed;
        proc.Disposed += EclipseInstanceDisposed;

        proc.StartInfo.FileName = SelectedEclipseInstance.Exec;

        proc.Start();
    });
}
Community
  • 1
  • 1
blfuentes
  • 2,731
  • 5
  • 44
  • 72

2 Answers2

1

Have you tried

proc.WaitForExit()

You can even run proc.WaitForExit() on another thread if you need the rest of the code to continue executing and run your EclipseInstanceClosed method once its done.

If the process has actually stopped this method will return. If it never returns it means the process has never stopped. Then you need to troubleshoot why it does not stop.


Before launching the first instance of your app, get a list of all running Javaw.exe and their PIDs. Keep this list. Once you launch a new instance of your app, recheck the javaw.exe list. Find the new one. Create a "reference" to this process to monitor it like you have written your code above.

var proc = Process.GetProcessById(id);

Keep monitoring that and do your stuff.

If you launch a new process, redo the logic above. List all javaw.exe right before and right after to get your Process.Id to monitor.

If each javaw.exe is run with arguments, there are ways to get these arguments as well to narrow down your target process if the method above is not good enough.

Wolf5
  • 16,600
  • 12
  • 59
  • 58
  • process.WaitForExit() can only be used to track whether launching process has completed/exited. But OP is launching an eclipse application and he wants to know when this launched application is closed. – Kurubaran Nov 07 '14 at 08:39
  • Ah. I am not familiar with how Eclipse works its running processes. I assume its one long living process running several "apps" then. If eclipse does not close down when the application closes then his code above will not work at all. That code is for the process closing down. – Wolf5 Nov 07 '14 at 08:47
0
proc.Exited += EclipseInstanceClosed;

Please note that above code will not notify when the launched application is closed. process.Exited event is used to know when the associated process is completed( The process you triggered by calling Process.Start()). But if you want to check if the launched application is running/closed you could write some monitoring code as follows within your EclipseInstanceClosed event.

void EclipseInstanceClosed(object sender, EventArgs e)
{
  while (true)
  {
     Process runningEclipseProcess = Process.GetProcessesByName("ExclipeProcessName").FirstOrDefault();

     if (runningEclipseProcess != null)
     {
        //Exclipe is not closed. Wait for 1 sec and check again.
        Thread.Sleep(1000);
     }
     else
     {
        //Exclipe is closed. Notify the user
        MessageBox.Show("Eclipse was closed!");
        break;
    }
  }     
}
Kurubaran
  • 8,696
  • 5
  • 43
  • 65
  • 1
    this is not working if you have several instance of same application with same process name. – Hamid Pourjam Nov 07 '14 at 08:58
  • @HamidP Agreed. As long as OP doesn't have such scenario it should be fine. – Kurubaran Nov 07 '14 at 09:04
  • 1
    As I said, all processes are "javaw.exe" and also I cannot identify individually by processName because if I run different instances of the same exec they share same name. – blfuentes Nov 07 '14 at 09:08
  • 3
    You can monitor that. Take a snapshot of all javaw.exe running before you start an instance. Keep the info (Process.Id) for each of these. Then once you launched a new instance, take a new snapshot. The newest javaw.exe will have a Process.Id you do not have in that list you just kept. You can then monitor EACH of these new process by the Process.Id you aquired with the code you originally created (proc = Process.GetProcessById(id). – Wolf5 Nov 07 '14 at 09:29