El método más común es utilizar un mutex, similar a la siguiente:
int WINAPI WinMain(...)
{
const char szUniqueNamedMutex[] = "com_mycompany_apps_appname";
HANDLE hHandle = CreateMutex(NULL, TRUE, szUniqueNamedMutex);
if(ERROR_ALREADY_EXISTS == GetLastError())
{
// Program already running somewhere
return(1); // Exit program
}
// Program runs...
// Upon app closing:
ReleaseMutex(hHandle); // Explicitly release mutex
CloseHandle(hHandle); // close handle before terminating
return(1);
}
Usted tiene que asegurarse de que cierre correctamente - un accidente de programa que no se retire el mutex, posiblemente, podría evitar la programa se ejecute de nuevo, aunque en teoría el sistema operativo limpiará cualquier mutexes colgando una vez que el proceso termina.
Otro método utilizado comúnmente es buscar títulos de ventana para el título del programa:
HWND hWnd=::FindWindow(LPCTSTR lpClassName, // pointer to class name
LPCTSTR lpWindowName // pointer to window name
);
Si es nula, entonces la ventana no se ha encontrado, por lo tanto, el programa no se está ejecutando. Puede usar esto para enfocar la aplicación que se está ejecutando antes de cerrar esta nueva instancia, de modo que el usuario no se pregunte por qué la aplicación no se abrió.
if(hWnd != NULL)
{
ShowWindow(hWnd,SW_NORMAL);
// exit this instance
return(1);
}
¿Por qué no se debería permitir? Pregunto porque si el programa es algo así como un servidor que escucha un número de puerto fijo, realmente no tienes que hacer nada especial. – hvd
@hvd, hay muchos tipos de programas que no deberían permitir la ejecución de instancias múltiples. De lo contrario, no habría mutexes en las bibliotecas del sistema. – Griwes
Sí, esa aplicación es un Servidor, pero se puede ejecutar para varias instancias pero no con el mismo argumento. si pasamos el mismo argumento desde el servicio de ventana e iniciamos el ABC.exe y desde el acceso directo de escritorio con el mismo argumento ABC.exe, el segundo no debería iniciarse. –