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
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
