Como tener una única instancia de mi aplicación en WPF


Un tema recurrente en WPF es como conseguir que solo haya una instancia de tu aplicación, existen varios métodos para ello que vamos a ir viendo.

1.Comprobando si existe el proceso.

Quizá sea la forma mas simple, en la lista de procesos chequeamos si ya existe

1 public partial class App : Application 2 { 3 protected override void OnStartup(StartupEventArgs e) 4 { 5 // Get Reference to the current Process 6 Process thisProc = Process.GetCurrentProcess(); 7 // Check how many total processes have the same name as the current one 8 if (Process.GetProcessesByName(thisProc.ProcessName).Length > 1) 9 { 10 // Si ya existe sacamos un mensaje. 11 MessageBox.Show("La aplicación ya se esta ejecutando."); 12 Application.Current.Shutdown(); 13 return; 14 } 15 16 base.OnStartup(e); 17 } 18 }

El único problema que tiene este método es que si a tu aplicación se le pasa argumentos no nos serviría.

 

2.Usando WindowsFormsApplicationBase

En la librería Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase existe una característica que  nos permite controlar si ya se esta ejecutando nuestra aplicación y soluciona el problema anterior. Realmente se utiliza igual que en Windows Forms, eliminamos los ficheros App.xaml y App.cs de manera que quitamos el punto de entrada de nuestra aplicación, añadimos la clase Main con el siguiente código.

1 class Program 2 { 3 [STAThread] 4 public static void Main(string[] args) 5 { 6 WindowsFormsApp wrapper = new WindowsFormsApp(); 7 wrapper.Run(args); 8 } 9 }

La clase Wrapper tendría el código:

 

1 class WindowsFormsApp : WindowsFormsApplicationBase 2 { 3 private App _wpfApp; 4 5 public WindowsFormsApp() 6 { 7 // habilitar una unica instancia 8 IsSingleInstance = true; 9 } 10 11 protected override bool OnStartup(StartupEventArgs e) 12 { 13 14 _wpfApp = new App(); 15 _wpfApp.Run(); 16 17 return false; 18 } 19 20 protected override void OnStartupNextInstance( 21 StartupNextInstanceEventArgs e) 22 { 23 if (e.CommandLine.Count > 0) 24 { 25 _wpfApp.ProcessArguments(e.CommandLine.ToArray()); 26 } 27 } 28 }

Por ultimo la clase App

 

1 class App : Application 2 { 3 protected override void OnStartup(StartupEventArgs e) 4 { 5 base.OnStartup(e); 6 7 MainWindow window = new MainWindow(); 8 window.Show(); 9 } 10 11 public void ProcessArguments(string[] args) 12 { 13 //Procesamos los parametros 14 15 } 16 }

Como veis sencillo, aunque a mi no me gusta, ya que metemos características de Winforms, tenemos que añadir librerías y es demasiado código para lo que queremos hacer.

3.Utilizando Mutex

Yo es la que utilizo siempre, es bastante sencilla de implementar y de mantener.

1 private static bool FirstInstance 2 { 3 get 4 { 5 bool created; 6 string name = Assembly.GetEntryAssembly().FullName; 7 8 Mutex mutex = new Mutex(true, name, out created); 9 return created; 10 } 11 }

Si recordamos como funciona Mutex, la primera instancia que lo crea pasa a ser propietaria del thread y con la variable created, controlamos si es la instancia que ha creado Mutex, sino es asi nos devolverá un false , de manera que nuestra App.Xaml.cs quedaría  

1 protected override void OnStartup(StartupEventArgs e) 2 { 3 if (FirstInstance) 4 base.OnStartup(e); 5 else 6 { 7 MessageBox.Show("Application is already running."); 8 Application.Current.Shutdown(); 9 } 10 }

Como veis mas sencillo que en el caso anterior y mucho mas elegante.

Libros de WPF recomendados

Pro Wpf in C# 2008: Windows Presentation Foundation with .Net 3.5
WPF 4 Unleashed
WPF Recipes in C# 2008: A Problem-Solution Approach

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *