Índice de la sección dedicada a .NET (en el Guille) Cómo... en .NET

Saber si hay otra copia de nuestra aplicación en ejecución
(El equivalente a PrevInstance de VB6, con código para VB y C#)

Publicado el 24/Ago/2004
Actualizado el 31/Ago/2004
Autor: Guillermo 'guille' Som


Si solo queremos que hay una copia en ejecución de nuestra aplicación, podemos usar el código que te muestro aquí para que eso no ocurra.
Este sería el equivalente al PrevInstance de VB6.
En el código que publiqué hace un par de años usaba API, pero en esta ocasión utilizo la clase Process.

Nota del 31/Ago:
En este link tienes cómo hacerlo si quieres que realmente haya una copia en ejecución aunque se cambie el nombre del ejecutable.

 

Para hacer esta comprobación, vamos a usar la clase Process, en particular el método GetProcessByName, el cual devuelve un array con los procesos que se están ejecutando, si a ese método le pasamos el nombre de un ejecutable (realmente el nombre de un proceso) y el array devuelto no está vacío, querrá decir que dicho proceso está en ejecución.

Veamos el código tanto para Visual Basic como para C#.

Para facilitar la lectura del código, tendremos que importar el espacio de nombres System.Diagnostics, que es donde se encuentra la clase Process.

En el siguiente código se usa Process.GetCurrentProcess.ProcessName para averiguar el nombre del proceso actual y después lo usamos con el método Process.GetProcessesByName para saber si está en ejecución. Este método devuelve un array del tipo Process con cada uno de los procesos que coincidan con ese nombre, por tanto lo que hacemos es comprobar si el valor devuelto (que es un array) contiene más de un elemento, ya que debemos tener en cuenta que ese método devolverá un elementos porque habrá "contado" el proceso actual, y si tiene más de uno... es que hay otra copia.
Esta comprobación la podemos hacer de dos formas:
1- Usando la propiedad Length, si es mayor que uno es que hay más de una copia.
2- Comprobando el límite superior del array, si es mayor que cero, es que hay más de una copia.

VB:

Dim enEjecucion As Boolean

' comprobando la cantidad de elementos del array
enEjecucion = Process.GetProcessesByName(Process.GetCurrentProcess.ProcessName).Length > 1

' comprobando el límite superior del array
enEjecucion = Process.GetProcessesByName(Process.GetCurrentProcess.ProcessName).GetUpperBound(0) > 0

 

C#:

bool enEjecucion;

// comprobando la cantidad de elementos del array
enEjecucion = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1;

// comprobando el límite superior del array
enEjecucion = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).GetUpperBound(0) > 0;

...


Revisión usando la clase Mutex (31/Ago/04)
Para que sólo haya una copia en ejecución aunque se cambie el nombre del ejecutable

El otro día, hablando con otros MVPs sobre el tema de comprobar si había una sola aplicación en ejecución, al comentar sobre el procedimiento este que usa la clase Process para comprobar si el proceso actual estaba más de una vez, surgió el caso de que el usuario podía cambiarle el nombre de la aplicación y en ese caso no se detectaría que estuviese dos veces, ya que el nombre del proceso (ProcessName) suele hacer referencia al nombre del ejecutable, pero sin la extensión.
El colega Eduardo A. Morcillo comentó que usando la clase Mutex del espacio de nombres System.Threading se podía comprobar que sólo existiera una copia en ejecución, independientemente del nombre que tuviese el ejecutable.

El código (adaptado) quedaría de la siguiente forma:
La variable de tipo Boolean nuevaInstancia, que se pasa por referencia al constructor, tendrá el valor verdadero si no hay otra instancia ejecutándose o un valor falso si ya existe otra copia funcionando, en el segundo parámetro del constructor indicaremos el nombre único que queramos usar para identificar a esta aplicación.

VB:

Dim miMutex As System.Threading.Mutex
Dim nuevaInstancia As Boolean
'
miMutex = New System.Threading.Mutex(True, "El nombre para esta aplicación", nuevaInstancia)

 

 

C#:

System.Threading.Mutex miMutex;
bool nuevaInstancia;
//
miMutex = new System.Threading.Mutex(true, "El nombre para esta aplicación", out nuevaInstancia);

 

...


la Luna del Guille o... el Guille que está en la Luna... tanto monta...