15

ADDITIONAL INFORMATION

Again i am writing on the above issue (Preventing multiple instances of my application)

the code works for if i start two instances from programe menu/desktop shortcut. but in my envrironment,

one instance is running from Window Service.

another from Desktop shortcut with Same parameter.

Any help how to write the code ?

Sweta Priya
  • 183
  • 2
  • 2
  • 7
  • Why shouldn't it be allowed? I'm asking because if it the program is something like a server that listens on a fixed port number, you don't really have to do anything special. –  Jan 10 '12 at 07:02
  • @hvd, there are many types of programs, that shouldn't allow execution of multiple instances. Otherwise, there wouldn't be mutexes in system libraries. – Griwes Jan 10 '12 at 07:22
  • Yes that application is a Server, but it can be run for multiple instances but not with Same argument. if we pass same argument from window service and starts the ABC.exe and from Desktop shortcut with same argument ABC.exe the 2nd one should not start. – Sweta Priya Jan 10 '12 at 07:29
  • @Griwes I'm not saying there's no good reason for it, I know there are plenty of valid reasons. But depending on the reason, I thought there might be a simpler solution. –  Jan 10 '12 at 07:56
  • @hvd, like what? Mutex seems to be perfect in this situation - he wants prevention for running with same argument - and here it is, named mutex. – Griwes Jan 10 '12 at 11:35
  • @Griwes If (using my example) the answer is "it shouldn't be allowed because no two servers can listen on the same port", then you shouldn't check for the same arguments if different arguments can *also* cause the same port number to be used, or if the same arguments can cause different port numbers to be used (if a separate configuration file has since been updated). In that case, comparing command lines is a non-solution. You think (I think) that "prevent running twice with the same arguments" is the problem to be solved. I think it is probably a means to solve a different problem. –  Jan 10 '12 at 11:56

5 Answers5

22

The most common method is to use a mutex, similar to the following:

int WINAPI WinMain(...)
{
   const char szUniqueNamedMutex[] = "com_mycompany_apps_appname";
   HANDLE hHandle = CreateMutex( NULL, TRUE, szUniqueNamedMutex );
   if( ERROR_ALREADY_EXISTS == GetLastError() )
   {
      // Program already running somewhere
      return(1); // Exit program
   }

   // Program runs...

   // Upon app closing:
   ReleaseMutex( hHandle ); // Explicitly release mutex
   CloseHandle( hHandle ); // close handle before terminating
   return( 1 );
}

You have to make sure that you close properly - a program crash that doesn't remove the mutex could possibly prevent the program from running again, though in theory the OS will clean up any dangling mutexes once the process ends.

Another method commonly used is to search window titles for the program title:

HWND hWnd=::FindWindow(LPCTSTR lpClassName, // pointer to class name
                       LPCTSTR lpWindowName // pointer to window name
                       );

If it's null, then the window was not found, therefore the program is not running. You can use this to bring focus to the running app before closing this new instance, so the user isn't left wondering why the app didn't open.

if(hWnd != NULL)
{
   ShowWindow(hWnd,SW_NORMAL);
   // exit this instance
   return(1);
}
Adam Davis
  • 91,931
  • 60
  • 264
  • 330
  • Aren't you forgetting `ReleaseMutex` ? – Jesse Good Jan 10 '12 at 07:29
  • @Jesse It's released when you CloseHandle it, but if you are interested in being explicit, a call to ReleaseMutex would be fine. http://msdn.microsoft.com/en-us/library/windows/desktop/ms724211%28v=vs.85%29.aspx – Adam Davis Jan 10 '12 at 07:34
  • I don't think that is true. I think you have to call `ReleaseMutex`. Check out this [SO question](http://stackoverflow.com/questions/5034339/closehandle-on-a-mutex-before-releasemutex-what-happens) and also read the remarks for [CreateMutex](http://msdn.microsoft.com/en-us/library/aa914601.aspx). However, I do realize it probably doesnt matter in this case though. – Jesse Good Jan 10 '12 at 07:44
  • 4
    @Jesse It does seem a bit murky, but it does say, "Use the CloseHandle function to close the handle. The system closes the handle automatically when the process terminates. **The mutex object is destroyed when its last handle has been closed.**" (emphasis mine) However I'll add it in the code example. – Adam Davis Jan 10 '12 at 08:03
  • Unless I'm mistaken, I thought that the OS is guaranteed to close this, even if the app doesn't exit cleanly. – moltenform Nov 11 '15 at 04:21
  • 1
    @jmnben: That's correct. When a process terminates, the OS closes all handles owned by that process. In fact, I would argue that manually closing a mutex, guarding against multiple concurrent instances at least partially defies the purpose. If you want to make sure that the process is gone before you allow another instance, let the OS clean up the handle for you. Closing the handle too early may open a window of opportunity, where the guarded resource can be accessed concurrently. – IInspectable Dec 24 '15 at 01:56
  • Just worth noting if you're a multiprocess purist, the second method isn't 100% guaranteed. There is a possible race condition if the first process is pre-empted by the OS between getting `NULL` from `FindWindow` and calling `CreateWindow`. Granted, the window of opportunity is extremely short, but it's always a risk. – dgnuff Oct 20 '19 at 16:33
13

Here is a simple solution that works most of the time:

CreateEvent(NULL, FALSE, FALSE, "MyEvent");
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
    // Do Stuff
    return FALSE;
}

Another way:

CreateSemaphore(NULL, TRUE, TRUE, "MySemaphore");
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
   // Do Stuff
   return FALSE;
}

And another way:

CreateMutex(NULL, TRUE, "MyMutex");
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
   // Do Stuff
   return FALSE;
}

As, the other answer mentioned, CreateMutex is the most common but it isnt perfect. If you want a really thorough solution and why the above ways are no good, check this link on Codeproject.

Jesse Good
  • 50,901
  • 14
  • 124
  • 166
  • Note that these objects cannot use the same string (for lpName) if you use them in conjunction, otherwise they will give a different error. – Andrew Jul 17 '15 at 05:06
5

TLDR: The only safe and general way to prevent multiple instances of the same process is to use a mutex, since only this is guaranted to not give you a race condition.

Here you have a nice article about the subject. I used it when having to do something similar and the solution is working perfectly: AvoidingMultipleInstances.

Hakaishin
  • 2,550
  • 3
  • 27
  • 45
Javier De Pedro
  • 2,219
  • 4
  • 32
  • 49
3

Also i've seen this solution, without GetLastError():

    HANDLE hMutex = CreateMutexA(NULL, FALSE, "my mutex");
    DWORD dwMutexWaitResult = WaitForSingleObject(hMutex, 0);
    if (dwMutexWaitResult != WAIT_OBJECT_0)
    {
        MessageBox(HWND_DESKTOP, TEXT("This application is already running"), TEXT("Information"), MB_OK | MB_ICONINFORMATION);
        CloseHandle(hMutex);
    }
shtille
  • 133
  • 5
3

You are looking for named mutex (named after argument, if it is what should disallow the app to run in multiple instances).

Griwes
  • 8,805
  • 2
  • 43
  • 70