John Pietrar John Pietrar - 2 months ago 7
C# Question

How to know if external application was closed?

How can I say if a winform whas closed do ...?

bool isRunning = false;
foreach (Process clsProcess in Process.GetProcesses()) {
if (clsProcess.ProcessName.Contains("Notepad"))
{
isRunning = true;
break;
}
}


The code above always checks if the process exists but the code is slow for what I want it to do.So is there a way to check if the
Notepad
process was actually closed instead of always looping to see if its there?

Answer

You can use Win32_ProcessStopTrace which indicates that a process is terminated.

ManagementEventWatcher watcher;
public Form1()
{
    InitializeComponent();
    watcher = new ManagementEventWatcher("Select * From Win32_ProcessStopTrace");
    watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
    watcher.Start();
}

void watcher_EventArrived(object sender, EventArrivedEventArgs e)
{
    if ((string)e.NewEvent["ProcessName"] == "notepad.exe")
        MessageBox.Show("Notepad closed");
}

protected override void OnFormClosed(FormClosedEventArgs e)
{
    watcher.Stop();
    watcher.Dispose();
    base.OnFormClosed(e);
}

Don't forget to add a reference to System.Management and add using System.Management;

Note

  • Above method notifies you about closing of all processes, regardless of the time they are opened, before or after your application run.

  • If you want to monitor closing of an specific instance of notepad which you know, you can use such criteria:

    if ((UInt32)e.NewEvent["ProcessID"]==knownProcessId)
    
  • If you want to check if any instance of notepad is open, you can use such criteria:

    if (System.Diagnostics.Process.GetProcessesByName("notepad").Any())
    
  • If you don't want to notified about the processes which may be opened after your application starts, you can get existing notepad processes and subscribe to their Exited event:

    private void Form1_Load(object sender, EventArgs e)
    {
        System.Diagnostics.Process.GetProcessesByName("notepad").ToList()
              .ForEach(p => {
                  p.EnableRaisingEvents = true;
                  p.Exited += p_Exited;
              });
    }
    void p_Exited(object sender, EventArgs e)
    {
        MessageBox.Show("Notepad closed");
    }
    
Comments