2010-11-16 107 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. 
} 
相關問題