Friday, March 19, 2010

WPF Single Instance

This is a very simple way to create a WPF single instance application.


What you need ?

1.Download the file WpfSingleInstance.cs here  (adding the actual code at the bottom of this post.)
2.Include the WpfSingleInstance.cs file to your project
3.Add the following code to your App.xaml.cs file.

protected override void OnStartup(StartupEventArgs e)
{
    WpfSingleInstance.Make("MyWpfApplicationName",this);

    base.OnStartup(e);
}
Thats it !

From here you can customize how you want to handle user alert, you can either alert with message saying "Another instance is already running" or just set focus on the already running instance and bring it to the front !

Hope this helps !

using System;
using System.Threading;
using System.Windows;

namespace WpfSingleInstanceByEventWaitHandle
{
    public static class WpfSingleInstance
    {

        internal static void Make(String name, Application app)
        {

            EventWaitHandle eventWaitHandle = null;
            String eventName = Environment.MachineName + "-" + Environment.CurrentDirectory.Replace('\\', '-') + "-" + name;

            bool isFirstInstance = false;

            try
            {
                eventWaitHandle = EventWaitHandle.OpenExisting(eventName);
            }
            catch
            {
                // it's first instance
                isFirstInstance = true;
            }

            if (isFirstInstance)
            {
                eventWaitHandle = new EventWaitHandle(
                    false,
                    EventResetMode.AutoReset,
                    eventName);

                ThreadPool.RegisterWaitForSingleObject(eventWaitHandle, waitOrTimerCallback, app, Timeout.Infinite, false);

                // not need more
                eventWaitHandle.Close();
            }
            else
            {
                eventWaitHandle.Set();

                // For that exit no interceptions
                Environment.Exit(0);
            }
        }


        private static void waitOrTimerCallback(Object state, Boolean timedOut)
        {
            Application app = (Application)state;
            app.Dispatcher.BeginInvoke(new activate(delegate() {
                Application.Current.MainWindow.Activate();
                }), null);
        }


        private delegate void activate();

    }
}
Thanks to IliyaTretyakov