Publicado el 17/Jul/2002
Actualizado el 16/Jul/2002
Saber si una aplicación ya se está ejecutando, y si es así, mostrarla (traerla al frente)
Nota:
Esta es la versión del código para .NET Framework normal, si quieres ver el código para el .NET Compact Framework, sigue este link.De lo que aquí se trata es de usar dos funciones del API de Windows: FindWindow y SetForegroundWindow.
El código se usa dentro del procedimientos Main, el cual tendrás que añadirlo, ya que por defecto no se incluye al crear un nuevo proyecto de Visual Basic .NET (en C# siempre se incluye el código de Main).Se busca una "ventana" con el título indicado, y si se encuentra, se activa (se trae al frente) y se cierra la aplicación actual (que sería la segunda copia), esto es equivalente al App.PrevInstance del VB6.
Este código también forma parte de la librería que estoy haciendo con algunas funciones útiles, pero se puede usar directamente en el código del formulario. Lo único que habría que hacer es declararlas como Shared; ya que al usarse desde el procedimiento Main, que también es un procedimiento compartido (Shared), nos obliga a declararlas Shared, por la sencilla razón que dentro de los procedimientos compartidos sólo podemos usar otros procedimientos o variables que a su vez estén compartidas.
No lo he probado en Windows 98, pero se supone que debe funcionar; esto lo digo por la forma en que están declaradas las funciones, ya que no se indica, al menos en la función FindWindow, si es Ansi o Unicode, se supone que el CLR (runtime) del .NET Framework decidirá que función tendrá que utilizar.
#Region " Para saber si una aplicación está en memoria " ' <System.Runtime.InteropServices.DllImport("user32.dll", _ EntryPoint:="SetForegroundWindow")> _ Public Function SetForegroundWindow( _ ByVal hWnd As IntPtr) As Boolean End Function ' ' <System.Runtime.InteropServices.DllImport("user32.dll", _ EntryPoint:="FindWindow")> _ Public Function FindWindow( _ ByVal lpClassName As String, _ ByVal lpWindowName As String) As IntPtr End Function ' Public ceroIntPtr As New IntPtr(0) ' ' #End RegionPara usarla, declarar este módulo Sub Main dentro del código de la clase del formulario, habrá que indicar tanto el texto de la barra de título como el nombre de la clase (el nombre del formulario).
Public Shared Sub Main() ' Se comprueba si la aplicación está en memoria Dim nWnd As IntPtr ' nWnd = FindWindow(Nothing, "Form1") If nWnd.Equals(ceroIntPtr) Then ' Si no está, se carga la actual Application.Run(New Form1()) Else ' Si ya está, se activa SetForegroundWindow(nWnd) ' y se sale de la actual Application.Exit() End If End Sub
Este es el código para C#.
#region Para saber si una aplicación está en memoria [DllImport("user32.dll", EntryPoint="FindWindow")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", EntryPoint="SetForegroundWindow")] public static extern bool SetForegroundWindow(IntPtr hWnd); #endregion
Y esta sería la forma de comprobarlo, (el código debe estar en Main)
////// The main entry point for the application. /// [STAThread] static void Main() { IntPtr nWnd = FindWindow(null, "Form1"); if (nWnd.Equals(new System.IntPtr(0))) { Application.Run(new Form1()); } else { SetForegroundWindow(nWnd); Application.Exit(); } }