Impedir que una aplicación se ejecute dos veces
¿Cómo podemos evitar que una aplicación se ejecute más de una vez de forma simultánea?
En Windows existe un método sencillo: usar un mutex.
El nombre mutex es una abreviatura de un algoritmo de exclusión mutua. Es un dispositivo que se usa normalmente para evitar concurrencia, es decir para controlar el acceso de determinadas zonas de código que tienen acceso a recursos compartidos.
En nuestro caso, el recurso al que tenemos que limitar el acceso es el ordenador. Como se trata de un recurso que puede ser compartido, sólo limitaremos el acceso a nuestro programa, es decir, cuando nuestro programa esté accediendo al sistema operativo impedirá que otras instancias del mismo programa puedan acceder a él.
Un mutex es ideal para este propósito, ya que sólo puede estar en posesión de un proceso a la vez. Si un proceso tiene un manipulador de un mutex, no es posible que otro pueda obtenerlo.
De todos modos, para el propósito de este artículo no usaremos el mutex de ese modo, sencillamente intentaremos crear un mutex con un nombre determinado. Si el mutex no existía previamente, continuamos con la ejecución de la aplicación, si existía, abandonamos la ejecución.
Para obtener un manipulador para un mutex usaremos la función del API de Windows CreateMutex. Los dos primeros parámetros no nos importan demasiado. El primero es un descriptor de seguridad, que para este propósito nos basta con el descriptor por defecto. El segundo sirve para obtener la propiedad del mutex cuando es creado o no. Para nuestro caso es indiferente, ya que sólo verificaremos si el mutex existe o no. El tercero es el nombre del mutex. Usaremos un nombre único para nuestra aplicación.
Hay que tener presente que lo que impedirá que nuestra aplicación se ejecute es la presencia del mutex, de modo que este mecanismo no sólo impide que dos instancias del mismo programa se ejecuten a la vez, también impedirá la ejecución de cualquier otra aplicación que use el mismo nombre para el mutex.
// Prueba de mutex // Mayo 2013 Con Clase // Salvador Pozo #include <windows.h> #include <iostream> using namespace std; int main() { bool EnEjecucion; //mutex = CreateMutex(NULL, FALSE, "PROGRAMA_EN_EJECUCION"); EnEjecucion = (GetLastError() == ERROR_ALREADY_EXISTS || GetLastError() == ERROR_ACCESS_DENIED); if(EnEjecucion) { MessageBox(NULL, "El programa ya está en ejecución", "Probar mutex", MB_OK); return 0; } // Resto del programa aquí... cin.get(); return 0; }
Alternativamente a usar mutex podemos hacer lo mismo con un fichero de disco. Si no existe, lo creamos al iniciar la aplicación y lo borramos al terminar. Si existe, cerramos la aplicación.
El problema de este método es que si la aplicación termina de forma imprevista el fichero no se borra, y no se podrá ejecutar la aplicación hasta que borremos el fichero de forma manual.
La idea es siempre crear un objeto global desde el punto de vista del sistema operativo, que sólo exista mientras la aplicación esté en ejecución. La ventaja del mutex es que se destruye automáticamente cuando la aplicación termina, independientemente del modo en que termine, aunque sea a causa de un error.