Click here to Skip to main content
Licence CPOL
First Posted 27 Mar 2009
Views 25,277
Bookmarked 26 times

How to check if an application is already running

By | 27 Mar 2009 | Article
How to determine if an application is already running and switch to it.

Introduction

For a project of my own, I had the task to check if the same application is already running every time the application is started by the user. If the application is already running, it must be switched to the foreground and the currently started process must be closed.

Using the code

I am using the Visual C++ 9.0 Standard Edition and the project type is MFC. We will use functions from <tlhelp32.h>. I am using WinXP.

In the string-table of your resource, you must have a string with the ID AFX_IDS_APP_TITLE.

It must contain the application name of your executable without .exe. For example, if your executable file is named “frTKO.exe”, then the string-resource must be “frTKO”.

First, we will include the necessary header file.

#include <tlhelp32.h>

The function to do our work is as follows:

// Checks, if an application with this name is running
//
// bShow ..... TRUE: bring application to foreground, if running 
//             FALSE: only check, don't move to the application
//
// return: FALSE: application is not running
//         TRUE: application runs
BOOL AppIsAllreadyRunning(BOOL bShow/*=TRUE*/)
{
    BOOL bRunning=FALSE;
    CString strAppName;
    strAppName.LoadString(AFX_IDS_APP_TITLE);
    strAppName += _T(".exe");
    DWORD dwOwnPID = GetProcessId(GetCurrentProcess());
    HANDLE hSnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    PROCESSENTRY32* processInfo=new PROCESSENTRY32;
    processInfo->dwSize=sizeof(PROCESSENTRY32);
    int index=0;
    while(Process32Next(hSnapShot,processInfo)!=FALSE)
    {
        if (!strcmp(processInfo->szExeFile,strAppName))
        {
            if (processInfo->th32ProcessID != dwOwnPID)
            {
                if (bShow)
                    EnumWindows(ShowAppEnum,processInfo->th32ProcessID);
                bRunning=TRUE;
                break;
            }
        }
    }
    CloseHandle(hSnapShot);
    delete processInfo;
    return bRunning;
}

To get access to the window of the running application, we use EnumWindows(), which needs a helper-function for enumerating processes:

// Helper callback-function for function AppIsAllreadyRunning()
// see description of EnumWindows() for details
BOOL CALLBACK ShowAppEnum (HWND hwnd, LPARAM lParam)
{
    DWORD dwID;
    CString strAppName;
    strAppName.LoadString(AFX_IDS_APP_TITLE);
    GetWindowThreadProcessId(hwnd, &dwID) ;
    if(dwID == (DWORD)lParam)
    {
        char title[256];
        CString strBuffer;
        GetWindowText(hwnd,title,256);
        strBuffer = title;
        if (strBuffer.Left(strAppName.GetLength()) == strAppName)
        {
            if (!IsWindowVisible(hwnd))
                ShowWindow(hwnd,SW_SHOW); 
            SetForegroundWindow(hwnd);
        }
    }
    return TRUE;
}

Now, you place a call to your function as the first in the InitInstance() of your app-class. You can check the return-code of the function to return FALSE if an instance is already running.

BOOL CfrTeakoApp::InitInstance()
{
#ifndef _DEBUG
    if (AppIsAllreadyRunning())
        return FALSE;
#endif

Don’t forget to define the functions in the header-file:

BOOL AppIsAllreadyRunning(BOOL bShow=TRUE);
BOOL CALLBACK ShowAppEnum( HWND hwnd, LPARAM lParam );

That’s all.

License

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

About the Author

Rob A. Fraydl

Team Leader

Austria Austria

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralMy vote of 2 PinmemberCharles Oppermann19:47 2 Aug '11  
Questionerror C2065: 'ShowAppEnum' : undeclared identifier Pinmemberdinh_vu_vt20050:33 24 Mar '11  
GeneralMy vote of 1 Pinmembercccfff7774:46 6 Aug '10  
GeneralIt is a wrong way! PinmemberVictor Nijegorodov22:18 30 Mar '09  
GeneralMy vote of 1 [modified] PinmemberVictor Nijegorodov22:09 30 Mar '09  
General[My vote of 1] I'm afraid this is not the right way to do it. PinPopularmemberwtwhite18:31 30 Mar '09  
GeneralGood article but ... PinmemberNacereddine0:22 28 Mar '09  
GeneralRe: Good article but ... Pinmemberkcynic15:08 30 Mar '09  
GeneralRe: Good article but ... PinmemberVaKa20:25 30 Mar '09  
GeneralRe: Good article but ... PinmemberMartin Jimenez5:02 31 Mar '09  
If you want your mutex to be "seen" across sessions prefixit with "Global\\".
 
Cheers

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

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

Permalink | Advertise | Privacy | Mobile
Web01 | 2.5.120604.1 | Last Updated 27 Mar 2009
Article Copyright 2009 by Rob A. Fraydl
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid