Windows阻止多个实例代码无法正常工作

时间:2015-01-26 16:00:37

标签: c++ windows multiple-instances

我正在使用CreateEvent来阻止我的应用程序的多个实例:

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

然而,在启动时我注意到这不起作用: 显示桌面后,我会自动运行一个批处理脚本,尝试启动程序的多个实例。批处理脚本成功,我确实可以看到多个实例。

到目前为止的调查:

  • OutputDebug显示每个实例都没有获得ERROR_ALREADY_EXISTS
  • ProcessExplorer.exe显示每个实例都能够获取事件“MyEvent”的句柄。

任何人都可以想到为什么会发生这种情况,以及我如何解决它?

1 个答案:

答案 0 :(得分:1)

我们使用下面的函数,它位于我们的常用实用程序DLL中。该方法源自Microsoft文章,解释了如何防止WIN32中的多个实例。

#define STRICT
#include <stdheaders.h>

HANDLE   ghSem;

BOOL IExist( LPSTR lpszWindowClass )
{
   HWND     hWndMe;
   int      attempt;

   for( attempt=0; attempt<2; attempt++ )
   {
      // Create or open a named semaphore.
      ghSem = CreateSemaphore( NULL, 0, 1, lpszWindowClass );
      // Close handle and return NULL if existing semaphore was opened.
      if( (ghSem != NULL) && 
          (GetLastError() == ERROR_ALREADY_EXISTS) )
      {  // Someone has this semaphore open...
         CloseHandle( ghSem );
         ghSem = NULL;
         hWndMe = FindWindow( lpszWindowClass, NULL );
         if( hWndMe && IsWindow(hWndMe) )
         {  // I found the guy, try to wake him up
            if( SetForegroundWindow( hWndMe ) )
            {  // Windows says we woke the other guy up
               return TRUE;
            }
         }
         Sleep(100); // Maybe the semaphore will go away like the window did...
      }
      else
      {  // If new semaphore was created, return FALSE.
         return FALSE;
      }
   }
   // We never got the semaphore, so we must 
   // behave as if a previous instance exists
   return TRUE;
}

在你的WinMain中做这样的事情:

if( IExist("MyWindowClass") )
{
   return 1;
}

当然,当你不是第一个实例时(例如激活现有实例),你可以用你需要做的任何事情替换回报。