窗口可防止多个实例代码不起作用

Windows prevent multiple instances code not working

本文关键字:代码 不起作用 实例 可防止 窗口      更新时间:2023-10-16

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

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

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

到目前为止的调查:

  • 输出调试显示每个实例都不会得到ERROR_ALREADY_EXISTS
  • ProcessExplorer.exe 显示每个实例都能够获取事件"MyEvent"的句柄。

谁能想到为什么会发生这种情况,以及我该如何解决它?

我们使用下面的函数,它位于我们的通用实用程序 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;
}

当然,您可以将返回替换为当您不是第一个实例时需要执行的任何操作(例如激活现有实例)。