Hay muchas formas de hacer que una aplicación de escritorio (Windows Form, WPF) ejecute una y solo una instancia a la vez. Existen muy buenos artículos en internet que hablan de este tema, pero en este post quiero mostrar la que para mi es la manera mas fácil y rápida de lograr esta funcionalidad.

Lo primero que tenemos que hacer cuando creamos el proyecto donde queremos implementar esta característica es agregar la referencia a ensamblado “Microssoft.VisualBasic.dll”

Microsoft.VisualBasic.dll

Luego creamos una clase que herede de WindowsFormsApplicationBase para ello necesitamos incluir el siguiente usgin

using Microsoft.VisualBasic.ApplicationServices;

La implementación de la clase puede ser algo como lo que sigue:

class MyApp : WindowsFormsApplicationBase
{
    //Creamos el constructor y especificamos la forma en que 
    //la aplicación inicializará el objeto My.User de VisualBasic
    public MyApp() : base(AuthenticationMode.ApplicationDefined)
    {
        //Especificamos que solo queremos que se ejecute una solo instancia de la aplicación
        IsSingleInstance = true;
    }

    protected override void OnCreateMainForm()
    {
        //Indicamos cual será el formulario principal de la aplicación
        MainForm = new Form1();
		base.OnCreateMainForm();
    }
}

Una vez hecho esto solo hay que sustituir la llamada a Form1 en el método inicial de la aplicación por la llamada al método Run de la clase que hemos creado.

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        
        //Application.Run(new Form1()); esto es lo que sustituimos por la línea que sigue a continuación

        new MyApp().Run(new string[0]);
    }
}

y con esto garantizamos que la aplicación solo ejecute una solo instancia.

Pasando Argumentos

Existen ocasiones donde es necesario pasarle argumentos a la aplicación para que esta tenga un comportamiento especial en función de los dichos parámetros. En este caso podríamos pasar los argumentos en la llamada al método Run de la aplicación.

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        
        //Application.Run(new Form1());
        new MyApp().Run(args);
    }
}

y luego en los métodos OnStartup y OnStartupNextInstance manejar el comportamiento de la aplicación en función de dichos parámetros.

protected override bool OnStartup(StartupEventArgs eventArgs)
{
    //Hacer algo con los parámetros recibidos (eventArgs.CommandLine)
    return base.OnStartup(eventArgs);
}

protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
{
    //Hacer algo con los parámetros recibidos (eventArgs.CommandLine)
    base.OnStartupNextInstance(eventArgs);
}

Como hemos podido ver esta es una forma muy sencilla de implementar una aplicación que solo abra una instancia a la vez. Más información sobre la clase WindowsFormsApplicationBase en MSDN

Puedes descargarte el código fuente desde aquí


 |