[c#] How can I know if a process is running?

When I get a reference to a System.Diagnostics.Process, how can I know if a process is currently running?

This question is related to c# .net process

The answer is


It depends on how reliable you want this function to be. If you want to know if the particular process instance you have is still running and available with 100% accuracy then you are out of luck. The reason being that from the managed process object there are only 2 ways to identify the process.

The first is the Process Id. Unfortunately, process ids are not unique and can be recycled. Searching the process list for a matching Id will only tell you that there is a process with the same id running, but it's not necessarily your process.

The second item is the Process Handle. It has the same problem though as the Id and it's more awkward to work with.

If you're looking for medium level reliability then checking the current process list for a process of the same ID is sufficient.


There are many problems associated with this, as other have seemed to partially address:

  • Any instance members are not guaranteed to be thread safe. Meaning there are race conditions that may occur with the lifetime of the snapshot while trying to evaluate the properties of the object.
  • The process handle will throw Win32Exception for ACCESS DENIED where permissions for evaluating this and other such properties aren't allowed.
  • For ISN'T RUNNING status, an ArgumentException will also be raised when trying to evaluate some of its properties.

Whether the properties others have mentioned are internal or not, you can still obtain information from them via reflection if permission allows.

var x = obj.GetType().GetProperty("Name", BindingFlags.NonPublic | BindingFlags.Instance);

You could pinvoke Win32 code for Snapshot or you can use WMI which is slower.

HANDLE CreateToolhelp32Snapshot(
  DWORD dwFlags,
  DWORD th32ProcessID
);

Another option would be to OpenProcess / CloseProcess, but you will still run into the same issues with exceptions being thrown same as before.

For WMI - OnNewEvent.Properties["?"]:

  • "ParentProcessID"
  • "ProcessID"
  • "ProcessName"
  • "SECURITY_DESCRIPTOR"
  • "SessionID"
  • "Sid"
  • "TIME_CREATED"

It depends on how reliable you want this function to be. If you want to know if the particular process instance you have is still running and available with 100% accuracy then you are out of luck. The reason being that from the managed process object there are only 2 ways to identify the process.

The first is the Process Id. Unfortunately, process ids are not unique and can be recycled. Searching the process list for a matching Id will only tell you that there is a process with the same id running, but it's not necessarily your process.

The second item is the Process Handle. It has the same problem though as the Id and it's more awkward to work with.

If you're looking for medium level reliability then checking the current process list for a process of the same ID is sufficient.


This is the simplest way I found after using reflector. I created an extension method for that:

public static class ProcessExtensions
{
    public static bool IsRunning(this Process process)
    {
        if (process == null) 
            throw new ArgumentNullException("process");

        try
        {
            Process.GetProcessById(process.Id);
        }
        catch (ArgumentException)
        {
            return false;
        }
        return true;
    }
}

The Process.GetProcessById(processId) method calls the ProcessManager.IsProcessRunning(processId) method and throws ArgumentException in case the process does not exist. For some reason the ProcessManager class is internal...


Maybe (probably) I am reading the question wrongly, but are you looking for the HasExited property that will tell you that the process represented by your Process object has exited (either normally or not).

If the process you have a reference to has a UI you can use the Responding property to determine if the UI is currently responding to user input or not.

You can also set EnableRaisingEvents and handle the Exited event (which is sent asychronously) or call WaitForExit() if you want to block.


It depends on how reliable you want this function to be. If you want to know if the particular process instance you have is still running and available with 100% accuracy then you are out of luck. The reason being that from the managed process object there are only 2 ways to identify the process.

The first is the Process Id. Unfortunately, process ids are not unique and can be recycled. Searching the process list for a matching Id will only tell you that there is a process with the same id running, but it's not necessarily your process.

The second item is the Process Handle. It has the same problem though as the Id and it's more awkward to work with.

If you're looking for medium level reliability then checking the current process list for a process of the same ID is sufficient.


Process.GetProcesses() is the way to go. But you may need to use one or more different criteria to find your process, depending on how it is running (i.e. as a service or a normal app, whether or not it has a titlebar).


Synchronous solution :

void DisplayProcessStatus(Process process)
{
    process.Refresh();  // Important


    if(process.HasExited)
    {
        Console.WriteLine("Exited.");
    }
    else
    {
        Console.WriteLine("Running.");
    } 
}

Asynchronous solution:

void RegisterProcessExit(Process process)
{
    // NOTE there will be a race condition with the caller here
    //   how to fix it is left as an exercise
    process.Exited += process_Exited;
}

static void process_Exited(object sender, EventArgs e)
{
   Console.WriteLine("Process has exited.");
}

Process.GetProcesses() is the way to go. But you may need to use one or more different criteria to find your process, depending on how it is running (i.e. as a service or a normal app, whether or not it has a titlebar).


Despite of supported API from .Net frameworks regarding checking existing process by process ID, those functions are very slow. It costs a huge amount of CPU cycles to run Process.GetProcesses() or Process.GetProcessById/Name().

A much quicker method to check a running process by ID is to use native API OpenProcess(). If return handle is 0, the process doesn't exist. If handle is different than 0, the process is running. There's no guarantee this method would work 100% at all time due to permission.


Synchronous solution :

void DisplayProcessStatus(Process process)
{
    process.Refresh();  // Important


    if(process.HasExited)
    {
        Console.WriteLine("Exited.");
    }
    else
    {
        Console.WriteLine("Running.");
    } 
}

Asynchronous solution:

void RegisterProcessExit(Process process)
{
    // NOTE there will be a race condition with the caller here
    //   how to fix it is left as an exercise
    process.Exited += process_Exited;
}

static void process_Exited(object sender, EventArgs e)
{
   Console.WriteLine("Process has exited.");
}

I tried Coincoin's solution :
Before processing some file, I copy it as a temporary file and open it.
When I'm done, I close the application if it is still open and delete the temporary file :
I just use a Process variable and check it afterwards :

private Process openApplication;  
private void btnOpenFile_Click(object sender, EventArgs e) {  
    ...
    // copy current file to fileCache  
    ...  
    // open fileCache with proper application
    openApplication = System.Diagnostics.Process.Start( fileCache );  
}

Later I close the application :

 ...   
openApplication.Refresh(); 

// close application if it is still open       
if ( !openApplication.HasExited() ) {
    openApplication.Kill();  
}

// delete temporary file  
System.IO.File.Delete( fileCache );

It works ( so far )


I tried Coincoin's solution :
Before processing some file, I copy it as a temporary file and open it.
When I'm done, I close the application if it is still open and delete the temporary file :
I just use a Process variable and check it afterwards :

private Process openApplication;  
private void btnOpenFile_Click(object sender, EventArgs e) {  
    ...
    // copy current file to fileCache  
    ...  
    // open fileCache with proper application
    openApplication = System.Diagnostics.Process.Start( fileCache );  
}

Later I close the application :

 ...   
openApplication.Refresh(); 

// close application if it is still open       
if ( !openApplication.HasExited() ) {
    openApplication.Kill();  
}

// delete temporary file  
System.IO.File.Delete( fileCache );

It works ( so far )


It depends on how reliable you want this function to be. If you want to know if the particular process instance you have is still running and available with 100% accuracy then you are out of luck. The reason being that from the managed process object there are only 2 ways to identify the process.

The first is the Process Id. Unfortunately, process ids are not unique and can be recycled. Searching the process list for a matching Id will only tell you that there is a process with the same id running, but it's not necessarily your process.

The second item is the Process Handle. It has the same problem though as the Id and it's more awkward to work with.

If you're looking for medium level reliability then checking the current process list for a process of the same ID is sufficient.


Process.GetProcesses() is the way to go. But you may need to use one or more different criteria to find your process, depending on how it is running (i.e. as a service or a normal app, whether or not it has a titlebar).


You can instantiate a Process instance once for the process you want and keep on tracking the process using that .NET Process object (it will keep on tracking till you call Close on that .NET object explicitly, even if the process it was tracking has died [this is to be able to give you time of process close, aka ExitTime etc.])

Quoting http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspx:

When an associated process exits (that is, when it is shut down by the operation system through a normal or abnormal termination), the system stores administrative information about the process and returns to the component that had called WaitForExit. The Process component can then access the information, which includes the ExitTime, by using the Handle to the exited process.

Because the associated process has exited, the Handle property of the component no longer points to an existing process resource. Instead, the handle can be used only to access the operating system’s information about the process resource. The system is aware of handles to exited processes that have not been released by Process components, so it keeps the ExitTime and Handle information in memory until the Process component specifically frees the resources. For this reason, any time you call Start for a Process instance, call Close when the associated process has terminated and you no longer need any administrative information about it. Close frees the memory allocated to the exited process.


Maybe (probably) I am reading the question wrongly, but are you looking for the HasExited property that will tell you that the process represented by your Process object has exited (either normally or not).

If the process you have a reference to has a UI you can use the Responding property to determine if the UI is currently responding to user input or not.

You can also set EnableRaisingEvents and handle the Exited event (which is sent asychronously) or call WaitForExit() if you want to block.


string process = "notepad";
if (Process.GetProcessesByName(process).Length > 0)
{
    MessageBox.Show("Working");
}
else
{
    MessageBox.Show("Not Working");
}

also you can use a timer for checking the process every time


This is the simplest way I found after using reflector. I created an extension method for that:

public static class ProcessExtensions
{
    public static bool IsRunning(this Process process)
    {
        if (process == null) 
            throw new ArgumentNullException("process");

        try
        {
            Process.GetProcessById(process.Id);
        }
        catch (ArgumentException)
        {
            return false;
        }
        return true;
    }
}

The Process.GetProcessById(processId) method calls the ProcessManager.IsProcessRunning(processId) method and throws ArgumentException in case the process does not exist. For some reason the ProcessManager class is internal...


Maybe (probably) I am reading the question wrongly, but are you looking for the HasExited property that will tell you that the process represented by your Process object has exited (either normally or not).

If the process you have a reference to has a UI you can use the Responding property to determine if the UI is currently responding to user input or not.

You can also set EnableRaisingEvents and handle the Exited event (which is sent asychronously) or call WaitForExit() if you want to block.


You can instantiate a Process instance once for the process you want and keep on tracking the process using that .NET Process object (it will keep on tracking till you call Close on that .NET object explicitly, even if the process it was tracking has died [this is to be able to give you time of process close, aka ExitTime etc.])

Quoting http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspx:

When an associated process exits (that is, when it is shut down by the operation system through a normal or abnormal termination), the system stores administrative information about the process and returns to the component that had called WaitForExit. The Process component can then access the information, which includes the ExitTime, by using the Handle to the exited process.

Because the associated process has exited, the Handle property of the component no longer points to an existing process resource. Instead, the handle can be used only to access the operating system’s information about the process resource. The system is aware of handles to exited processes that have not been released by Process components, so it keeps the ExitTime and Handle information in memory until the Process component specifically frees the resources. For this reason, any time you call Start for a Process instance, call Close when the associated process has terminated and you no longer need any administrative information about it. Close frees the memory allocated to the exited process.


reshefm had a pretty nice answer; however, it does not account for a situation in which the process was never started to begin with.

Here is a a modified version of what he posted.

    public static bool IsRunning(this Process process)
    {
        try  {Process.GetProcessById(process.Id);}
        catch (InvalidOperationException) { return false; }
        catch (ArgumentException){return false;}
        return true;
    }

I removed his ArgumentNullException because its actually suppose to be a null reference exception and it gets thrown by the system anyway and I also accounted for the situation in which the process was never started to begin with or the close() method was used to close the process.


Synchronous solution :

void DisplayProcessStatus(Process process)
{
    process.Refresh();  // Important


    if(process.HasExited)
    {
        Console.WriteLine("Exited.");
    }
    else
    {
        Console.WriteLine("Running.");
    } 
}

Asynchronous solution:

void RegisterProcessExit(Process process)
{
    // NOTE there will be a race condition with the caller here
    //   how to fix it is left as an exercise
    process.Exited += process_Exited;
}

static void process_Exited(object sender, EventArgs e)
{
   Console.WriteLine("Process has exited.");
}

string process = "notepad";
if (Process.GetProcessesByName(process).Length > 0)
{
    MessageBox.Show("Working");
}
else
{
    MessageBox.Show("Not Working");
}

also you can use a timer for checking the process every time


Despite of supported API from .Net frameworks regarding checking existing process by process ID, those functions are very slow. It costs a huge amount of CPU cycles to run Process.GetProcesses() or Process.GetProcessById/Name().

A much quicker method to check a running process by ID is to use native API OpenProcess(). If return handle is 0, the process doesn't exist. If handle is different than 0, the process is running. There's no guarantee this method would work 100% at all time due to permission.


Process.GetProcesses() is the way to go. But you may need to use one or more different criteria to find your process, depending on how it is running (i.e. as a service or a normal app, whether or not it has a titlebar).


This is the simplest way I found after using reflector. I created an extension method for that:

public static class ProcessExtensions
{
    public static bool IsRunning(this Process process)
    {
        if (process == null) 
            throw new ArgumentNullException("process");

        try
        {
            Process.GetProcessById(process.Id);
        }
        catch (ArgumentException)
        {
            return false;
        }
        return true;
    }
}

The Process.GetProcessById(processId) method calls the ProcessManager.IsProcessRunning(processId) method and throws ArgumentException in case the process does not exist. For some reason the ProcessManager class is internal...


This should be a one-liner:

public static class ProcessHelpers {
    public static bool IsRunning (string name) => Process.GetProcessesByName(name).Length > 0;
}

There are many problems associated with this, as other have seemed to partially address:

  • Any instance members are not guaranteed to be thread safe. Meaning there are race conditions that may occur with the lifetime of the snapshot while trying to evaluate the properties of the object.
  • The process handle will throw Win32Exception for ACCESS DENIED where permissions for evaluating this and other such properties aren't allowed.
  • For ISN'T RUNNING status, an ArgumentException will also be raised when trying to evaluate some of its properties.

Whether the properties others have mentioned are internal or not, you can still obtain information from them via reflection if permission allows.

var x = obj.GetType().GetProperty("Name", BindingFlags.NonPublic | BindingFlags.Instance);

You could pinvoke Win32 code for Snapshot or you can use WMI which is slower.

HANDLE CreateToolhelp32Snapshot(
  DWORD dwFlags,
  DWORD th32ProcessID
);

Another option would be to OpenProcess / CloseProcess, but you will still run into the same issues with exceptions being thrown same as before.

For WMI - OnNewEvent.Properties["?"]:

  • "ParentProcessID"
  • "ProcessID"
  • "ProcessName"
  • "SECURITY_DESCRIPTOR"
  • "SessionID"
  • "Sid"
  • "TIME_CREATED"

Synchronous solution :

void DisplayProcessStatus(Process process)
{
    process.Refresh();  // Important


    if(process.HasExited)
    {
        Console.WriteLine("Exited.");
    }
    else
    {
        Console.WriteLine("Running.");
    } 
}

Asynchronous solution:

void RegisterProcessExit(Process process)
{
    // NOTE there will be a race condition with the caller here
    //   how to fix it is left as an exercise
    process.Exited += process_Exited;
}

static void process_Exited(object sender, EventArgs e)
{
   Console.WriteLine("Process has exited.");
}

reshefm had a pretty nice answer; however, it does not account for a situation in which the process was never started to begin with.

Here is a a modified version of what he posted.

    public static bool IsRunning(this Process process)
    {
        try  {Process.GetProcessById(process.Id);}
        catch (InvalidOperationException) { return false; }
        catch (ArgumentException){return false;}
        return true;
    }

I removed his ArgumentNullException because its actually suppose to be a null reference exception and it gets thrown by the system anyway and I also accounted for the situation in which the process was never started to begin with or the close() method was used to close the process.


Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to .net

You must add a reference to assembly 'netstandard, Version=2.0.0.0 How to use Bootstrap 4 in ASP.NET Core No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization .net Core 2.0 - Package was restored using .NetFramework 4.6.1 instead of target framework .netCore 2.0. The package may not be fully compatible Update .NET web service to use TLS 1.2 EF Core add-migration Build Failed What is the difference between .NET Core and .NET Standard Class Library project types? Visual Studio 2017 - Could not load file or assembly 'System.Runtime, Version=4.1.0.0' or one of its dependencies Nuget connection attempt failed "Unable to load the service index for source" Token based authentication in Web API without any user interface

Examples related to process

Fork() function in C How to kill a nodejs process in Linux? Xcode process launch failed: Security Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes Linux Script to check if process is running and act on the result CreateProcess error=2, The system cannot find the file specified How to make parent wait for all child processes to finish? How to use [DllImport("")] in C#? Visual Studio "Could not copy" .... during build How to terminate process from Python using pid?