How to detect a process start & end using c# in windows?
To do this without polling requires WMI. This is well supported in .net and you can use the ManagementEventWatcher
class to subscribe to WMI notifications.
This Code Project article illustrates how it is done. Here's an extract showing how straightforward it is.
notePad = new ProcessInfo("notepad.exe");
notePad.Started +=
new Win32Process.ProcessInfo.StartedEventHandler(this.NotepadStarted);
notePad.Terminated +=
new Win32Process.ProcessInfo.TerminatedEventHandler(this.NotepadTerminated);
Note that ProcessInfo
is a class implemented in the code attached to that article.
C# process.start, how do I know if the process ended?
MSDN System.Diagnostics.Process
If you want to know right now, you can check the HasExited
property.
var isRunning = !process.HasExited;
If it's a quick process, just wait for it.
process.WaitForExit();
If you're starting one up in the background, subscribe to the Exited event after setting EnableRaisingEvents to true.
process.EnableRaisingEvents = true;
process.Exited += (sender, e) => { /* do whatever */ };
How to detect when a new process is started?
You can use WMI (Windows Management Instrumentation) for this. It provides the Win32_ProcessStartTrace
and Win32_ProcessStopTrace
events for detecting when a process has been started/terminated.
Before we do anything you need to add a reference to the managed WMI library. Right-click your project in the Solution Explorer
and press Add Reference...
. Then go to the .NET
tab, select System.Management
and press OK.
Based on Hans Passant's answer:
Imports System.Management
Public Class Form1
Dim WithEvents ProcessStartWatcher As New ManagementEventWatcher(New WqlEventQuery("SELECT * FROM Win32_ProcessStartTrace"))
Dim WithEvents ProcessStopWatcher As New ManagementEventWatcher(New WqlEventQuery("SELECT * FROM Win32_ProcessStopTrace"))
Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles MyBase.Load
ProcessStartWatcher.Start()
ProcessStopWatcher.Start()
End Sub
Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs)
ProcessStartWatcher.Stop()
ProcessStopWatcher.Stop()
End Sub
Private Sub ProcessStartWatcher_EventArrived(sender As Object, e As System.Management.EventArrivedEventArgs) Handles ProcessStartWatcher.EventArrived
Dim ProcessName As String = e.NewEvent.Properties("ProcessName").Value
Dim PID As Integer = e.NewEvent.Properties("ProcessID").Value
MessageBox.Show(String.Format("Process ""{0}"" with ID {1} started.", ProcessName, PID))
End Sub
Private Sub ProcessStopWatcher_EventArrived(sender As Object, e As System.Management.EventArrivedEventArgs) Handles ProcessStopWatcher.EventArrived
Dim ProcessName As String = e.NewEvent.Properties("ProcessName").Value
Dim PID As Integer = e.NewEvent.Properties("ProcessID").Value
MessageBox.Show(String.Format("Process ""{0}"" with ID {1} stopped.", ProcessName, PID))
End Sub
End Class
This polls after a couple of seconds, so if you think this is too slow you could poll the __InstanceCreationEvent
and __InstanceDeletionEvent
events instead, which lets you specify the polling interval:
Const PollingInterval As Double = 2.0 'Seconds.
Dim WithEvents ProcessStartWatcher As New ManagementEventWatcher(New WqlEventQuery("SELECT * FROM __InstanceCreationEvent WITHIN " & PollingInterval & " WHERE TargetInstance ISA 'Win32_Process'"))
Dim WithEvents ProcessStopWatcher As New ManagementEventWatcher(New WqlEventQuery("SELECT * FROM __InstanceDeletionEvent WITHIN " & PollingInterval & " WHERE TargetInstance ISA 'Win32_Process'"))
(...form code...)
Private Sub ProcessStartWatcher_EventArrived(sender As Object, e As System.Management.EventArrivedEventArgs) Handles ProcessStartWatcher.EventArrived
Dim ProcessName As String = CType(e.NewEvent.Properties("TargetInstance").Value, ManagementBaseObject)("Name")
Dim PID As Integer = CType(e.NewEvent.Properties("TargetInstance").Value, ManagementBaseObject)("ProcessId")
MessageBox.Show(String.Format("Process ""{0}"" with ID {1} started.", ProcessName, PID))
End Sub
Private Sub ProcessStopWatcher_EventArrived(sender As Object, e As System.Management.EventArrivedEventArgs) Handles ProcessStopWatcher.EventArrived
Dim ProcessName As String = CType(e.NewEvent.Properties("TargetInstance").Value, ManagementBaseObject)("Name")
Dim PID As Integer = CType(e.NewEvent.Properties("TargetInstance").Value, ManagementBaseObject)("ProcessId")
MessageBox.Show(String.Format("Process ""{0}"" with ID {1} stopped.", ProcessName, PID))
End Sub
IMPORTANT: WMI polling can use a lot of CPU, so don't set too small intervals.
How to catch new processes starting and stopping?
Once you have the process object, you can add a handler to the "Exited" event to detect when it stops. Note that the "EnableRaisingEvents" property must be set to "True" for this to work, which you can set after you get the Process object using GetProcesses().
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.exited.aspx
Detect if launched process has been closed
The Process.Start() method returns a Process object.
Assign it to a variable and call WaitForExit() on.
Source: http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspx
Detect Single Windows Process Exit Event C#
You could use Process.WaitForExit()
The WaitForExit() overload is used to make the current thread wait
until the associated process terminates. This method instructs the
Process component to wait an infinite amount of time for the process
and event handlers to exit
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
process.StartInfo = startInfo;
startInfo.FileName = exeToRun;
process.Start();
process.WaitForExit();
How to determine is app exists? (Process.Start can find them)
There a key in the registry where you can find chrome.exe path:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe
How can I detect starting of process?
Well, your question is not clear but you should have a look Process.GetProcessesByName
method.
Creates an array of new Process components and associates them with
all the process resources on the local computer that share the
specified process name.
For example;
Process[] Runningcmd = Process.GetProcessesByName("cmd");
if (Runningcmd.Length == 0)
Console.WriteLine("Command Line is not running");
else
foreach(var p in Runningcmd )
{
p.Kill();
}
How can I know if a process is running?
This is a way to do it with the name:
Process[] pname = Process.GetProcessesByName("notepad");
if (pname.Length == 0)
MessageBox.Show("nothing");
else
MessageBox.Show("run");
You can loop all process to get the ID for later manipulation:
Process[] processlist = Process.GetProcesses();
foreach(Process theprocess in processlist){
Console.WriteLine("Process: {0} ID: {1}", theprocess.ProcessName, theprocess.Id);
}
Related Topics
Why Enums Require an Explicit Cast to Int Type
Trying to Insert Datetime.Now into Date/Time Field Gives "Data Type Mismatch" Error
Auto Create Database in Entity Framework Core
Check If Property Has Attribute
Using the C# Dispatcher in Wpf Applications
Self-Referencing Many-To-Many Recursive Relationship Code First Entity Framework
How to Remove Accents on a String
Serialize Property, But Do Not Deserialize Property in JSON.Net
Replace Parameter in Lambda Expression
Convert Word Doc and Docx Format to PDF in .Net Core Without Microsoft.Office.Interop
ASP.NET Webapi2 Enable Cors Not Working with Aspnet.Webapi.Cors 5.2.3
Method Overloading VS Optional Parameter in C# 4.0
How to Get Urls of Open Pages from Chrome and Firefox
The Name "Xyz" Does Not Exist in the Namespace "Clr-Namespace:Abc"