Single Instance of an Application Class

The question of how to force only one instance of an application to run at a time is often asked. Although this is not a difficult problem to solve, and indeed can be solved in several different ways, it comes up enough to create the need for a nice, canned solution. So here it is.

The class is called CSingleInstance, and is used as follows:

Include the header file to your CWinApp derived class's .H file:

...
#ifndef __AFXWIN_H__
 #error include 'stdafx.h' before including this file for PCH
#endif

#include "resource.h"       // main symbols
#include "SingleInstance.h"
...

Create a public member variable in you CWinApp derived class:

class CMyApp : public CWinApp
{
public:
    CMyApp();
    CSingleInstance m_singleInstance;
...

In InitInstance, call the classs Create() function with your main frames resource identifier (usually IDR_MAINFRAME):

BOOL CMyApp::InitInstance()
{
    // Check if an instance of our application is already running
    if ( !m_singleInstance.Create( IDR_MAINFRAME ) ) {
        // Return indicating that this instance
        // of the app should be shut down
        return FALSE;
    }

    AfxEnableControlContainer();
...

If the Create() function fails, the application is already running AND the running instance will be brought to the foreground. If the Create() function succeeds, then this is the first instance of the application.

In order to make this work, there is one more piece of code that needs to be inserted. In you main frames (usually CMainFrame) PreCreateWindow() function, add the following:

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    // TODO: Modify the Window class or styles here by modifying
    // the CREATESTRUCT cs
    CMyApp *app = (CMyApp *)AfxGetApp();
    // Set the class name to be the app's single instance class name
    cs.lpszClass = app->m_singleInstance.GetClassName();
...

Thats how to use it. If youre interested, heres how it works.

The Create() function for CSingleInstance contains two protected members: a mutex (m_hMutex ) and a class string (m_strClassName). The mutex is used as the mechanism for actually determining if the application is already running. If the CreateMutex() function succeeds, the application is the first instance. If it fails, the mutex has already been created by another instance of the application. The class string is used as a means of finding the main window of the application. It is created by taking the name of the application (pulled from the resource string) and appending " Class" to the end. Simple but effective. It gets attached to the main window during the main frames PreCreateWindow() function. When we want to find the window, we use FindWindowEx() with the class string.

Download demo project - 19KB

Download source - 2KB



Comments

  • Beautiful!

    Posted by richardwyllie on 05/23/2008 06:09pm

    I downloaded this and implemented it in 15 minutes. Works just great! Thanks. I have yet to try it in a CDialog-derived app, but I have great confidence...

    Reply
  • Very easy 2 use.

    Posted by Haranadh on 01/08/2006 01:22pm

    Thanks for posting this article. :)

    Reply
  • Doesn't work with Terminal Services

    Posted by Legacy on 07/24/2003 12:00am

    Originally posted by: Daniel Mihalache

    With Terminal Services (or Cytrix, or another similar product) running on the machine where I have the application and the HASP key, I can start two instances of the application from two different machines. That is because the mutex is created per session.

    In order to fix the problem, I created a global mutex by adding "Global\\" in front of the mutex name. It works fine for Windows 2000 and later versions, but on earlier versions the "Global" keyword is ignored.(see 'Kernel Object Name Spaces' in MSDN).

    The problem is serious. Even if I use a HASP key; the users can pay for one license and run as many applications as they want using Terminal Services.

    Does anyone know the solution to this problem?

    Reply
  • Dude, this rocks!

    Posted by Legacy on 06/28/2002 12:00am

    Originally posted by: Funky

    I've implemented a lot of other code claiming to do this but your code does it the best!

    Funky

    Reply
  • Here is the alternate way to restric multi instance

    Posted by Legacy on 01/09/2002 12:00am

    Originally posted by: Muhammed Owaid

    hi,
    
    I have another and easy way to do this task. by doing following steps.

    1 - Add this line "extern UINT WM_FIND_APP;" after you
    App class.
    eg.

    class CCDRWinTrayApp : public CWinApp
    {
    .....
    ....

    };

    ---> extern UINT WM_FIND_APP;

    2 - #include <afxmt.h> this header file to your App class
    ---> #include <afxmt.h>
    3 - Add a public member of HANDLE to your class like
    ---> HANDLE m_hMutex;

    4 - write following line before the constructor of your
    App class in Cpp file
    UINT WM_FIND_APP = RegisterWindowMessage("ULTRA_FIND_APP");

    ---> Eg:
    UINT WM_FIND_APP = RegisterWindowMessage("ULTRA_FIND_APP");
    CCDRWinTrayApp::CCDRWinTrayApp()
    {
    .......
    .......
    }

    5 - Add Distructor in your App class and put this code
    if (m_hMutex)
    CloseHandle (m_hMutex);
    in Distructor.

    Eg:
    CCDRWinTrayApp::~CCDRWinTrayApp()
    {
    if (m_hMutex)
    CloseHandle (m_hMutex);
    }

    6 - and finally add this code to Initinstance function of your App class.


    SetRegistryKey(_T("CDRWin Application 5.0"));

    LoadStdProfileSettings(); // Load standard INI

    m_hMutex = ::CreateMutex(NULL, FALSE, "ULTRA_MUTEX");
    if (GetLastError () == ERROR_ALREADY_EXISTS)
    {
    m_hMutex = NULL;

    DWORD dwRecipients = BSM_APPLICATIONS;

    ::BroadcastSystemMessage(
    BSF_POSTMESSAGE|BSF_IGNORECURRENTTASK,
    &dwRecipients,
    WM_FIND_APP,
    NULL,
    NULL
    );
    return FALSE;
    }

    I hope this will work If problem then feel free to mail me at owaid2000@yahoo.com
    enjoy!


    Reply
  • Making Multiple Instances of an Application run in the Same Process Space as different Threads

    Posted by Legacy on 09/28/2001 12:00am

    Originally posted by: Veena

    I have a problem regarding creating multiple instances of an application. Where I can register my problem?

    Reply
  • The bug in sample PreCreateWindow

    Posted by Legacy on 11/08/2000 12:00am

    Originally posted by: Maxim Milakov

    The recommended way to override CFrameWnd::PreCreateWindow contains a bug:
    
    

    CMyApp *app = (CMyApp *)AfxGetApp();
    cs.lpszClass = app->m_singleInstance.GetClassName();

    The string returned by GetClassName method is destroyed after the second line. We cannot rely the CFrameWnd::PreCreateWindow work ok.

    • OK, 2 simple changes:

      Posted by richardwyllie on 05/23/2008 06:21pm

      Change the definition of GetClassName in the CSingleInstance header and code files to: LPCTSTR GetClassName() const; and then change the code in PreCreateWindow to: cs.lpszClass = ((CMyDerivedWinApp *) AfxGetApp())->m_singleInstance.GetClassName(); Done...

      Reply
    Reply
  • Another way to do it in MSDN

    Posted by Legacy on 04/25/2000 12:00am

    Originally posted by: Linh Huynh

    you can implement this as shown in ONET32 MSDN

    Reply
  • Works but ...

    Posted by Legacy on 03/03/2000 12:00am

    Originally posted by: Manoj Ganger

    It doesn't bring the app to the foreground... for vc++6.0 MFC exe

    Reply
  • How to implement one instance dialog-based application?

    Posted by Legacy on 07/12/1999 12:00am

    Originally posted by: Wingsun

    Sometimes we need one dialog-based aplication only run one instance, how to implement with your examples?

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: August 20, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT When you look at natural user interfaces as a developer, it isn't just fun and games. There are some very serious, real-world usage models of how things can help make the world a better place – things like Intel® RealSense™ technology. Check out this upcoming eSeminar and join the panel of experts, both from inside and outside of Intel, as they discuss how natural user interfaces will likely be getting adopted in a wide variety …

  • Savvy enterprises are discovering that the cloud holds the power to transform IT processes and support business objectives. IT departments can use the cloud to redefine the continuum of development and operations—a process that is becoming known as DevOps. Download the Executive Brief DevOps: Why IT Operations Managers Should Care About the Cloud—prepared by Frost & Sullivan and sponsored by IBM—to learn how IBM SmartCloud Application services provide a robust platform that streamlines …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds