2010-11-16 102 views
10

我有一个应用程序使用套接字连接发送和接收来自另一个应用程序的数据。在创建套接字时,它使用端口4998。如何运行只有一个应用程序的实例

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

所以我想我的应用程序实例限制在一块。这意味着如果应用程序已经运行,并且有人试图通过点击exe或快捷方式图标再次运行该应用程序,它不应该运行该程序,而应该使现有的应用程序到顶端。

回答

10

您可能使用了命名互斥锁。从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; 
} 
+12

通过首先调用OpenMutex(),你有一个竞争条件。首先调用CreateMutex/Ex()。它会告诉你互斥锁是否已经存在。只有在CreateMutex()失败且出现ERROR_ACCESS_DENIED错误时才调用OpenMutex()。 – 2013-06-06 18:48:41

+0

关于如何在Win7 +上工作的任何提示?全球\ X互斥没有看到对方从不同的用户登录会话... – 2015-02-06 02:19:04

+1

@RomanPlášil他们实际上,你一定做错了什么 – paulm 2016-12-20 13:52:16

3

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

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

关闭m_hStartEvent在应用程序退出。

+0

如果CreatEvent()失败,则无法确定应用程序是否已在运行,因此您应该退出而不是继续。 – 2013-06-06 18:50:55

1

不要你已经有一个方法来检查,如果您的应用程序正在运行?谁需要互斥锁,如果端口已被占用,则知道该应用正在运行!

+0

是现在的我,而不是我出需要使用的过程中带给我的应用程序中的错误ID。任何帮助? – Simsons 2010-11-16 06:11:06

+5

仅仅因为该端口正在被使用,并不意味着您的应用程序正在使用它。 – 2010-11-16 06:21:35

+0

@ OJ,Good Catch。该端口可能被其他应用程序使用 – Simsons 2010-11-16 06:36:06

4

/* 我已经找到了必要的编辑工作要做。增加了一些额外的代码和编辑需要的。目前的一个对我来说是完美的。谢谢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; 
} 

/* 上面的代码工作,即使一个人试图打开第二个实例从一个不同的LOGIN离开第一次登录时打开与它的实例在运行。 */

2

当你的应用程序初始化,创建一个互斥体。如果它已经存在,找到现有的应用程序并将其放到前台。如果应用程序对其主窗口具有固定标题,则很容易找到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. 
} 
相关问题