如何只运行一个应用程序实例

Sim*_*ons 12 c++ sockets windows mfc

我有一个应用程序使用套接字连接来发送和接收来自另一个应用程序的数据.在创建套接字时,它使用端口4998.

这就是我的问题所在.一旦我启动我的应用程序,套接字就开始使用端口4998.因此,如果我想再次执行应用程序,那么我会收到套接字绑定错误.

所以我想将我的应用程序实例限制为一个.这意味着如果应用程序已经在运行并且某个人尝试通过单击exe或快捷方式图标再次运行应用程序,则它不应该运行该程序,而是应该将现有应用程序带到Top.

aco*_*aum 12

您可以使用命名的互斥锁.

文章中的代码示例:

WINAPI WinMain(
  HINSTANCE, HINSTANCE, LPSTR, int)
{
  try {
    // Try to open the mutex.
    HANDLE hMutex = OpenMutex(
      MUTEX_ALL_ACCESS, 0, "MyApp1.0");

    if (!hMutex)
      // Mutex doesn’t exist. This is
      // the first instance so create
      // the mutex.
      hMutex = 
        CreateMutex(0, 0, "MyApp1.0");
    else
      // The mutex exists so this is the
      // the second instance so return.
      return 0;

    Application->Initialize();
    Application->CreateForm(
      __classid(TForm1), &Form1);
    Application->Run();

    // The app is closing so release
    // the mutex.
    ReleaseMutex(hMutex);
  }
  catch (Exception &exception) {
    Application->
      ShowException(&exception);
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 通过首先调用OpenMutex(),您就会遇到竞争条件.首先调用CreateMutex/Ex().它会告诉您互斥锁是否已存在.仅当CreateMutex()因ERROR_ACCESS_DENIED错误而失败时才调用OpenMutex(). (13认同)

Kir*_*sky 5

在开始时创建命名事件并检查结果。如果事件已存在,则关闭应用程序。

BOOL CheckOneInstance()
{
    m_hStartEvent = CreateEventW( NULL, TRUE, FALSE, L"EVENT_NAME_HERE" );
    if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
        CloseHandle( m_hStartEvent ); 
        m_hStartEvent = NULL;
        // already exist
        // send message from here to existing copy of the application
        return FALSE;
    }
    // the only instance, start in a usual way
    return TRUE;
}
Run Code Online (Sandbox Code Playgroud)

m_hStartEvent在应用程序退出时关闭。

  • 如果 CreatEvent() 失败,您无法判断应用程序是否已经在运行,因此您应该退出,而不是继续。 (2认同)

小智 5

/*我找到了必要的编辑工作.添加了一些额外的代码和所需的编辑.现在对我来说非常合适.谢谢Kirill V. Lyadvinsky和Remy Lebeau的帮助!!

*/

bool CheckOneInstance()
{

    HANDLE  m_hStartEvent = CreateEventW( NULL, FALSE, FALSE, L"Global\\CSAPP" );

    if(m_hStartEvent == NULL)
    {
    CloseHandle( m_hStartEvent ); 
        return false;
    }


    if ( GetLastError() == ERROR_ALREADY_EXISTS ) {

        CloseHandle( m_hStartEvent ); 
        m_hStartEvent = NULL;
        // already exist
        // send message from here to existing copy of the application
        return false;
    }
    // the only instance, start in a usual way
    return true;
}
Run Code Online (Sandbox Code Playgroud)

/*上述代码即使在尝试打开第二个实例时也能正常工作,这个登录是通过其实例运行离开第一个登录的.*/


Edw*_*rey 5

应用程序初始化时,创建一个互斥锁.如果它已存在,请找到现有应用程序并将其置于前台.如果应用程序的主窗口具有固定标题,则很容易找到FindWindow.

m_singleInstanceMutex = CreateMutex(NULL, TRUE, L"Some unique string for your app");
if (m_singleInstanceMutex == NULL || GetLastError() == ERROR_ALREADY_EXISTS) {
    HWND existingApp = FindWindow(0, L"Your app's window title");
    if (existingApp) SetForegroundWindow(existingApp);
    return FALSE; // Exit the app. For MFC, return false from InitInstance.
}
Run Code Online (Sandbox Code Playgroud)

  • @LovelyHanibal 两个实例都可以在创建其窗口之前继续执行 FindWindow 检查。 (3认同)