Preventing multiple instances of my application [d

2019-01-22 15:01发布

This question already has an answer here:

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 ?

5条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-01-22 15:20

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.

查看更多
Deceive 欺骗
3楼-- · 2019-01-22 15:21

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.

查看更多
Luminary・发光体
4楼-- · 2019-01-22 15:22

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);
    }
查看更多
Viruses.
5楼-- · 2019-01-22 15:25

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);
}
查看更多
Root(大扎)
6楼-- · 2019-01-22 15:31

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

查看更多
登录 后发表回答