Inicio  |  Código  |  Utilidades  |  Enlaces  |  Buscar  |   
Error processing SSI file
Info

Valid XHTML 1.0!

Valid CSS!

Comprobar si hay una instancia previa de nuestra aplicación

Usando un mutex se puede chequear si está corriendo una instancia previa de nuestra aplicación. Dado que solo un hilo puede ser propietario de un mutex en un momento dado y estos son globales pueden aprovecharse para este uso. Cuando la primera instancia crea el mutex, tambien pasa a ser su propietario. Cuando una nueva instancia se ejecuta intenta tomar posesión del mutex, pero debido a que la instancia anterior es propietaria del mutex no puede hacerlo. Entonces si vemos que no se puede tomar posesión del mutex sabremos que hay otra instancia de la aplicación.

Una vez que detectamos que ya hay otra instancia, usando la clase System.Diagnostics.Process podemos obtener la ventana principal y activarla mediante una llamada a la API SetForegroundWindow

Copiar al portapapelesClase Edanmo.PrevInstance
Option Explicit On 
Option Strict On

Imports System
Imports System.Diagnostics
Imports System.Reflection
Imports System.Runtime.InteropServices
Imports System.Threading

Namespace Edanmo

    Public NotInheritable Class PrevInstance

        <DllImport("user32.dll")> _
        Private Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As Boolean
        End Function

        Private Shared _mutex As Mutex
        Private Shared _owned As Boolean

        Shared Sub New()

            ' Get the full name of the assembly
            ' that started the process
            Dim name As String = [Assembly].GetEntryAssembly().FullName

            ' Create a mutex using the assembly name.
            ' After the call _owned will be True if this thread 
            ' created and owns the mutex. Otherwise it will be 
            ' False, which means that a previous instance created it.
            _mutex = New Mutex(True, name, _owned)

        End Sub

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' Returns whether a previous instance of the process exists.
        ''' </summary>
        ''' <history>
        ''' 	[Eduardo Morcillo]	01/11/2004	Created
        ''' </history>
        ''' -----------------------------------------------------------------------------
        Public Shared ReadOnly Property Exists() As Boolean
            Get
                Return Not _owned
            End Get
        End Property

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' Returns an instance of System.Diagnostics.Process that represents the
        ''' previous instance process.
        ''' </summary>
        ''' <history>
        ''' 	[Eduardo Morcillo]	01/11/2004	Created
        ''' </history>
        ''' -----------------------------------------------------------------------------
        Public Shared ReadOnly Property Process() As Process
            Get

                If Not _owned Then

                    ' Get the current process
                    Dim currentProcess As Process = Process.GetCurrentProcess

                    ' Get the processes with the name of current process
                    Dim processes() As Process = Process.GetProcessesByName(currentProcess.ProcessName)

                    ' Enumerate the processes
                    For Each proc As Process In processes

                        ' Check if the process is not the current process
                        If proc.Id <> currentProcess.Id Then

                            ' Dispose the objects
                            currentProcess.Dispose()

                            Return proc

                        End If

                    Next

                End If

            End Get
        End Property

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' Activates the previous instance window.
        ''' </summary>
        ''' <returns>Whether the window was activated or not.</returns>
        ''' <history>
        ''' 	[Eduardo Morcillo]	01/11/2004	Created
        ''' </history>
        ''' -----------------------------------------------------------------------------
        Public Shared Function Activate() As Boolean

            Dim prev As Process = PrevInstance.Process

            If Not prev Is Nothing Then

                ' Refresh the process object to ensure
                ' it contains a valid window handle
                prev.Refresh()

                ' Set the foreground window 
                Activate = SetForegroundWindow(prev.MainWindowHandle())

                ' Dispose the object
                prev.Dispose()

            End If

        End Function

    End Class

End Namespace