How do I know if an external application is closed?

How can I tell if a closed winform does ...?

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

The above code always checks if a process exists, but the code is slow for what I want it to do. There is also a way to check if the process Notepadwas actually closed, and not always so that it can be seen

+4
source share
3 answers

You can use Win32_ProcessStopTracethat indicates that the process is complete.

ManagementEventWatcher watcher;
protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    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);
}

Do not forget to add a link to System.Managementand addusing System.Management;

Note

  • If you want to track the closing of a specific instance of a notebook that you know, you can use the following criteria:

    if ((UInt32)e.NewEvent["ProcessID"]==knownProcessId)
    
  • , - , :

    if (System.Diagnostics.Process.GetProcessesByName("notepad").Any())
    
  • EventArrived , , , Invoke.

  • , , . , , Exited:

    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");
    }
    
+9

, , :

bool isRunning = Process.GetProcessesByName("NotePad").FirstOrDefault() != null;

bool isRunning = Process.GetProcessesByName("notepad").Any();

, exe

+2

That should do the trick. This will create an event for you when the process dies. There is no need to go through the whole process.

public static event EventHandler ProcessDied;
public void CheckForProcess()
{

    InitializeComponent();
    ProcessDied += new EventHandler(Process_Died);
    AttachProcessDiedEvent("notepad", ProcessDied);

}

private  void AttachProcessDiedEvent( string processName,EventHandler e )
{
    Process isSelectedProcess=null;
    foreach (Process clsProcess in Process.GetProcesses())
    {
        if (clsProcess.ProcessName.Contains(processName))
        {
            isSelectedProcess = clsProcess;
            break;
        }
    }
    if(isSelectedProcess!=null)
    {
         isSelectedProcess.WaitForExit();
    }
    if(e!=null)
    {
        e.Invoke(processName, new EventArgs());
    }
}

private void Process_Died(object sender, EventArgs e)
{
    //Do Your work
}

Let me know if there are any problems.

+2
source

Source: https://habr.com/ru/post/1655843/


All Articles