2010-11-16 22 views
10

Tengo una aplicación que usa conexión de socket para enviar y recibir datos de otra aplicación. Al crear el socket, usa el puerto 4998.Cómo ejecutar solo una instancia de aplicación

Ahí es donde yace mi problema. Una vez que inicio mi aplicación, el socket comienza a usar el puerto 4998. Por lo tanto, si deseo ejecutar la aplicación nuevamente, recibo un error de encuadernación de socket.

por lo que quiero limitar mi instancia de aplicación a uno. Eso significa que si la aplicación ya se está ejecutando y alguien intenta ejecutar la aplicación nuevamente haciendo clic en el ícono de exe o acceso directo, no debería ejecutar el programa, sino que debería llevar la aplicación existente a la parte superior.

Respuesta

10

Puede utilizar el nombre mutex.

Ejemplo de código de la 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

Al llamar a OpenMutex() primero, tiene una condición de carrera. Llame a CreateMutex/Ex() primero. Le dirá si el mutex ya existe. Llame a OpenMutex() solo si CreateMutex() falla con un error ERROR_ACCESS_DENIED. –

+0

¿Algún consejo sobre cómo hacer que esto funcione en Win7 +? Global \ x mutex no ven unos a otros de diferentes sesiones de inicio de sesión de usuario ... –

+1

@ RomanPlášil que realmente hacen, usted debe haber hecho algo mal – paulm

3

Crea un evento con nombre al inicio y verifica el resultado. Cierre la aplicación si el evento ya existe.

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

Cerrar m_hStartEvent en la salida de la aplicación.

+0

Si CreatEvent() falla, no se puede decir si la aplicación ya se está ejecutando o no, por lo que debe salir, no continuar. –

1

no ¿Ya tiene una manera de comprobar si su aplicación se está ejecutando? ¿Quién necesita un Mutex, si el puerto ya está ocupado, sabes que la aplicación se está ejecutando?

+0

Sí Ahora en vez de mostrar el error necesito llevar mi solicitud mediante el proceso de CARNÉ DE IDENTIDAD. ¿Alguna ayuda? – Simsons

+5

El hecho de que el puerto se esté utilizando no significa que SU aplicación lo esté utilizando. –

+0

@ OJ, Buena captura. El puerto puede ser utilizado por otra aplicación – Simsons

4

/* he encontrado la edición necesario hacer. Se agregaron algunos códigos y ediciones adicionales que se necesitan. El presente está funcionando perfectamente para mí. Gracias, Kirill V. Lyadvinsky y Remy Lebeau por la ayuda !!

*/

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

/* El código anterior funciona incluso cuando se trata de abrir el segundo ejemplo desde un inicio de sesión diferente que abandona la primera LOGIN abierto con sus instancia en ejecución. */

2

Cuando la aplicación se inicia, crear un mutex. Si ya existe, busca la aplicación existente y ponla en primer plano. Si la aplicación tiene un título fijo para su ventana principal, es fácil de encontrar con 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. 
} 
Cuestiones relacionadas