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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4191465/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 14:47:07  来源:igfitidea点击:

How to Run Only One Instance of Application

c++windowssocketsmfc

提问by Simsons

I have a application which uses socket connection to send and receive data from another application. While creating socket it uses the port 4998 .

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

That is where my problem lie. Once I start my application the socket starts using port 4998. So if I want to execute the application again then I get socket binding error.

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

So I want to limit my application instance to one. That means if the application is already running and some one tries to run the application again by clicking the exe or shortcut icon it shouldn't run the program, instead it should bring the existing application to the Top.

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

采纳答案by acoolaum

You may used named mutex.

您可以使用命名互斥锁。

Code sample from the article:

文章中的代码示例:

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;
}

回答by krishna_kp

/* I have found the necessary editing to be done. Added some extra code and edits that are needed. The present one is working perfectly for me. Thank you, Kirill V. Lyadvinsky and Remy Lebeau for the help!!

/* 我发现需要进行必要的编辑。添加了一些额外的代码和所需的编辑。现在的对我来说非常完美。谢谢 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;
}

/* The above code works even when one tries to open up second instance FROM A DIFFERENT LOGIN LEAVING THE FIRST LOGIN OPEN with ITS INSTANCE RUNNING. */

/* 即使当一个人试图从一个不同的登录打开第二个实例时,上面的代码仍然有效,而它的实例正在运行。*/

回答by Edward Brey

When your application initializes, create a mutex. If it already exists, find the existing application and bring it to the foreground. If the application has a fixed title for its main window, it is easy to find with FindWindow.

当您的应用程序初始化时,创建一个互斥锁。如果它已经存在,找到现有的应用程序并将其置于前台。如果应用程序的主窗口有一个固定的标题,很容易找到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.
}

回答by Kirill V. Lyadvinsky

Create named event on the start and check the result. Close application if the event is already exist.

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

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;
}

Close m_hStartEventon the app exit.

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

回答by Ana Betts

Don't you already have a way to check if your application is running? Who needs a Mutex, if the port is already taken, you know that the app is running!

您是否已经有办法检查您的应用程序是否正在运行?谁需要互斥锁,如果端口已经被占用,你就知道应用程序正在运行!

回答by SELLAM

You can achieve this in your WindowMain function by calling the FindWindow function with the class name and the title of your main window at the very beginning. If the window exists you can either show a message to the user or simply show the window and then return:

您可以在 WindowMain 函数中通过在最开始时使用类名和主窗口的标题调用 FindWindow 函数来实现此目的。如果该窗口存在,您可以向用户显示一条消息,也可以简单地显示该窗口然后返回:

HWND hWnd = FindWindow(lzClassName, lzWindowText);
if(hWnd!=NULL)
{
    ShowWindow(hWnd, SW_SHOW);
    return 0;
}

WNDCLASSEX wcex;
/* register window class */
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_OWNDC;
wcex.lpfnWndProc = WindowProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;

...