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

  • On-demand Event Event Date: December 18, 2014 The Internet of Things (IoT) incorporates physical devices into business processes using predictive analytics. While it relies heavily on existing Internet technologies, it differs by including physical devices, specialized protocols, physical analytics, and a unique partner network. To capture the real business value of IoT, the industry must move beyond customized projects to general patterns and platforms. Check out this webcast and join industry experts as …

  • Today's agile organizations pose operations teams with a tremendous challenge: to deploy new releases to production immediately after development and testing is completed. To ensure that applications are deployed successfully, an automatic and transparent process is required. We refer to this process as Zero Touch Deployment™. This white paper reviews two approaches to Zero Touch Deployment--a script-based solution and a release automation platform. The article discusses how each can solve the key …

Most Popular Programming Stories

More for Developers

RSS Feeds