Click here to Skip to main content
15,881,898 members
Articles / Programming Languages / C#
Article

Writing a Win32 method to find if an application is already running

Rate me:
Please Sign up or sign in to vote.
3.88/5 (7 votes)
21 Jan 2006CPOL1 min read 57.2K   29   8
This article demonstrates how to write a method to find out if an application is already running in the background.

Introduction

I never was a Win32 developer. But sometimes, the .NET classes just don't make the cut. During my work, I needed a way to check if a certain application is running in the background. Obviously, I turned to the Process class that can be found in the System.Diagnostics namespace. Not much long after, I had this perfect looking piece of code:

C#
if (Process.GetProcessesByName(appName).Length > 0)
{
    // Warn the user that the application
    // is running in the background
}

It took our QA team less than a minute to tear these one-and-a-half lines of code to pieces. It turns out, that the Process class in .NET relies heavily on the PerfMon process/application. If the machine you're running has it disabled for some reason, you'll get an exception from the GetProcessesByName method. And it will take the exception a couple of seconds to be thrown. And that's the best case scenario. A couple of minutes spent with the other developers taught me that the usage of Process might just freeze or process. This was of course unacceptable.

The solution

I had no choice but to find another way. After some research, I found a couple of Win32 methods that I thought might help me: Process32First and Process32Next.

Now, I was ready to write my own IsProcessRunning method. Let's start with the different DllImport declarations:

C#
[DllImport("kernel32.dll")]
private static extern int Process32First(IntPtr hSnapshot, 
                                 ref PROCESSENTRY32 lppe);

[DllImport("kernel32.dll")]
private static extern int Process32Next(IntPtr hSnapshot, 
                                ref PROCESSENTRY32 lppe);

[DllImport("kernel32.dll", SetLastError=true)]
private static extern IntPtr CreateToolhelp32Snapshot(uint dwFlags, 
                                               uint th32ProcessID);

[DllImport("kernel32.dll", SetLastError=true)]
private static extern bool CloseHandle(IntPtr hSnapshot);

private const uint TH32CS_SNAPPROCESS = 0x00000002;

[StructLayout(LayoutKind.Sequential)]
private struct PROCESSENTRY32
{
    public uint dwSize;
    public uint cntUsage;
    public uint th32ProcessID;
    public IntPtr th32DefaultHeapID;
    public uint th32ModuleID;
    public uint cntThreads;
    public uint th32ParentProcessID;
    public int pcPriClassBase;
    public uint dwFlags;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)] public string szExeFile;
}

And here are some basic explanations of the methods:

  • PROCESSENTRY32 – This struct will obviously be used to keep the information of the different processes in the system.
  • Process32First/Process32Next – These methods will serve to enumerate all the processes.
  • CreateToolhelp32Snapshot – We'll use this method to create a snapshot of the system and the processes.

Now let's look at the code:

C#
public static bool IsProcessRunning(string applicationName)
{
    IntPtr handle = IntPtr.Zero;
    try
    {
        // Create snapshot of the processes
        handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        PROCESSENTRY32 info = new PROCESSENTRY32();
        info.dwSize = (uint)System.Runtime.InteropServices.
                      Marshal.SizeOf(typeof(PROCESSENTRY32));

        // Get the first process
        int first = Process32First(handle, ref info);
        // If we failed to get the first process, throw an exception
        if (first == 0)
            throw new Tzunami.Common.TzunamiException("Cannot" + 
                                        " find first process.");

        // While there's another process, retrieve it
        do
        {
            if (string.Compare(info.szExeFile, 
                  applicationName, true) == 0)
            {
                return true;
            }
        }
        while (Process32Next(handle, ref info) != 0);
    }
    catch
    {
        throw;
    }
    finally
    {
        // Release handle of the snapshot
        CloseHandle(handle);
        handle = IntPtr.Zero;
    }
    return false;
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Team Leader
Israel Israel
I currently work as the development manager in a company called Tzunami Inc. that develops a content migration solution for Microsoft SharePoint . Our product, called Tzunami Deployer is developed using C#.

Comments and Discussions

 
Questionver urgent - GetProcessesByName() method if I am a power user Pin
popaserban21-Nov-06 3:23
popaserban21-Nov-06 3:23 
QuestionWhat about this method? Pin
evgeniyn19-Nov-06 21:00
evgeniyn19-Nov-06 21:00 
Questionhow can i detect apllication is already dieed Pin
simboychan31-May-06 17:25
simboychan31-May-06 17:25 
GeneralAlternative implementation Pin
grinbergnir22-Jan-06 5:06
grinbergnir22-Jan-06 5:06 
GeneralRe: Alternative implementation Pin
entraped.isoLated22-Jul-07 19:12
entraped.isoLated22-Jul-07 19:12 
AnswerRe: Alternative implementation Pin
grinbergnir23-Jul-07 0:57
grinbergnir23-Jul-07 0:57 
QuestionComparing the first process? Pin
Marc Clifton21-Jan-06 12:59
mvaMarc Clifton21-Jan-06 12:59 
AnswerRe: Comparing the first process? Pin
Itay Sagui22-Jan-06 8:35
Itay Sagui22-Jan-06 8:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.