Archive for Enero, 2008

Evitar varias instancias de tu programa con un mutex con nombre en .Net

Enero 25, 2008  |  General  |  2 comments
Hoy he aprendido una nueva forma de evitar que se ejecute más de una instancia de tu software usando un mutex con nombre en .NET. El código en este caso es para VB.NET pero como sabéis es trivial pasarlo a C#.

 

Hasta ahora, para evitar múltiples instancias utilizaba la función Diagnostics.Process.GetProcessesByName(Diagnostics.Process.GetCurrentProcess.ProcessName). La idea consiste en comprobar si existe algún proceso con el nombre de tu programa ejecutándose en ese momento, y en caso afirmativo, terminar la ejecución de la nueva instancia que se intenta iniciar. A primera vista (puede que haya más), comentaré un par de puntos débiles de este método. En primer lugar, si el usuario cambia el nombre del ejecutable, adiós protección, el nombre del proceso cambia. Y en segundo lugar, si pretendes ejecutar tu programa en Windows Vista, la llamada a la función requiere permisos de administrador, y si no los tiene el programa (Botón derecho, ejecutar como administrador, por ejemplo) saltará una excepción bastante fea. Es una pena que tengamos que obligar al usuario a ejecutar nuestro programa en un nivel de confianza superior cuando realmente no es necesario. ¿La solución? Un mutex con nombre.

 

Un mutex con nombre es un objeto global (Objeto Kernel) que puede ser verificado desde cualquier programa. La idea consiste en comprobar si somos el “owner” de dicho mutex. Si somos la primera instancia, como lo estaremos creando seremos en efecto los propietarios. Cualquier intento de iniciar otra instancia de la aplicación, podrá comprobar que ese mutex ya está creado y que por lo tanto, otra instancia de la aplicación se está ejecutando.
Os copio aquí el código en VB.Net. No le he pasado el FxCop asi que es posible que no se ajuste perfectamente a la guía de diseño de clases de Microsoft para .Net.

 

 

Public Class MutexInstancia
Private Shared m_EsPrimeraInstancia As Boolean = False
Private Shared m_Mutex As System.Threading.Mutex = Nothing 

Public Shared ReadOnly Property ExistePrograma() As Boolean
Get
If m_Mutex Is Nothing Then
m_Mutex = New System.Threading.Mutex(True, "MiMutexGlobal", m_EsPrimeraInstancia)
End If

Return Not m_EsPrimeraInstancia
End Get
End Property

Private Sub New()
End Sub
End Class

 

If MutexInstancia.ExistePrograma Then
MessageBox.Show("El programa ya está abierto.", "Atención", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End
End If

 

Como podéis ver la clase es un simple contenedor de métodos estáticos, así que sacar la funcionalidad de aquí e incorporarla en otro lado si lo necesitáis. Eso sí, aseguraros de que el Mutex está vivo (No es null) durante toda la ejecución de la aplicación. Por último:



No sé si a alguien le será de utilidad, pero quien sabe.

Buenos desarrolladores y buenos habitos

Enero 19, 2008  |  General  |  5 comments
De lectura recomendada. Me ha gustado mucho la temática…¿Cómo reconocer a los buenos desarrolladores?

También via VariableNotFound encontré este interesante post sobre las pruebas de nivel para trabajar en Mono.

Y ya en otro orden de cosas, los 7 hábitos de las personas altamente innovadoras:

1. Trabajar duro
2. Evitar inhibiciones
3. Asumir riesgos, cometer errores
4. Escapar
5. Anotar las ideas
6. Encontrar patrones y combinarlos
7. Ser curioso

Un saludo