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?
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");
}
This should do the trick. It will create a event for you when the process dies. No need to loop through all the 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 issues.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With