How to Detect a Process Start & End Using C# in Windows

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



Leave a reply



Submit