Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
436 views
in Technique[技术] by (71.8m points)

c# - 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

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);
}

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

Note

  • 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())
    
  • The EventArrived will raise in a different thread than UI thread and if you need to manipulate UI, you need to use Invoke.

  • Above method notifies you about closing of all processes, regardless of the time they are opened, before or after your application run. 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");
    }
    

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...