【问题标题】:Windows prevent multiple instances code not workingWindows 防止多个实例代码不起作用
【发布时间】:2015-01-26 16:00:37
【问题描述】:

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

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

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

目前的调查:

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

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

【问题讨论】:

    标签: c++ windows multiple-instances


    【解决方案1】:

    我们使用下面的函数,它位于我们常用的实用程序 DLL 中。该方法源自微软的一篇文章,该文章解释了如何防止 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;
    }
    

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

    【讨论】:

      猜你喜欢
      • 2014-02-11
      • 2011-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-29
      • 2015-04-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多