WPF Single Instance Best Practices WPF Single Instance Best Practices wpf wpf

WPF Single Instance Best Practices


There are Several choices,

  • Mutex
  • Process manager
  • Named Semaphore
  • Use a listener socket

Mutex

Mutex myMutex ;private void Application_Startup(object sender, StartupEventArgs e){    bool aIsNewInstance = false;    myMutex = new Mutex(true, "MyWPFApplication", out aIsNewInstance);      if (!aIsNewInstance)    {        MessageBox.Show("Already an instance is running...");        App.Current.Shutdown();      }}

Process manager

private void Application_Startup(object sender, StartupEventArgs e){    Process proc = Process.GetCurrentProcess();    int count = Process.GetProcesses().Where(p=>         p.ProcessName == proc.ProcessName).Count();    if (count > 1)    {        MessageBox.Show("Already an instance is running...");        App.Current.Shutdown();     }}

Use a listener socket

One way to signal another application is to open a Tcp connection to it. Create a socket, bind to a port, and listen on a background thread for connections. If this succeeds, run normally. If not, make a connection to that port, which signals the other instance that a second application launch attempt has been made. The original instance can then bring its main window to the front, if appropriate.

“Security” software / firewalls might be an issue.

Single Instance Application C#.Net along with Win32


I wanted to have a bit better user experience - if another instance is already running let's activate it rather than showing an error about the second instance. Here is my implementation.

I use named Mutex for making sure that only one instance is running and named EventWaitHandle to pass notification from one instance to another.

App.xaml.cs:

/// <summary>Interaction logic for App.xaml</summary>public partial class App{    #region Constants and Fields    /// <summary>The event mutex name.</summary>    private const string UniqueEventName = "{GUID}";    /// <summary>The unique mutex name.</summary>    private const string UniqueMutexName = "{GUID}";    /// <summary>The event wait handle.</summary>    private EventWaitHandle eventWaitHandle;    /// <summary>The mutex.</summary>    private Mutex mutex;    #endregion    #region Methods    /// <summary>The app on startup.</summary>    /// <param name="sender">The sender.</param>    /// <param name="e">The e.</param>    private void AppOnStartup(object sender, StartupEventArgs e)    {        bool isOwned;        this.mutex = new Mutex(true, UniqueMutexName, out isOwned);        this.eventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, UniqueEventName);        // So, R# would not give a warning that this variable is not used.        GC.KeepAlive(this.mutex);        if (isOwned)        {            // Spawn a thread which will be waiting for our event            var thread = new Thread(                () =>                {                    while (this.eventWaitHandle.WaitOne())                    {                        Current.Dispatcher.BeginInvoke(                            (Action)(() => ((MainWindow)Current.MainWindow).BringToForeground()));                    }                });            // It is important mark it as background otherwise it will prevent app from exiting.            thread.IsBackground = true;            thread.Start();            return;        }        // Notify other instance so it could bring itself to foreground.        this.eventWaitHandle.Set();        // Terminate this instance.        this.Shutdown();    }    #endregion}

And BringToForeground in MainWindow.cs:

    /// <summary>Brings main window to foreground.</summary>    public void BringToForeground()    {        if (this.WindowState == WindowState.Minimized || this.Visibility == Visibility.Hidden)        {            this.Show();            this.WindowState = WindowState.Normal;        }        // According to some sources these steps gurantee that an app will be brought to foreground.        this.Activate();        this.Topmost = true;        this.Topmost = false;        this.Focus();    }

And add Startup="AppOnStartup" (thanks vhanla!):

<Application x:Class="MyClass.App"               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"             Startup="AppOnStartup">    <Application.Resources>    </Application.Resources></Application>

Works for me :)


For WPF just use:

public partial class App : Application{    private static Mutex _mutex = null;    protected override void OnStartup(StartupEventArgs e)    {        const string appName = "MyAppName";        bool createdNew;        _mutex = new Mutex(true, appName, out createdNew);        if (!createdNew)        {            //app is already running! Exiting the application              Application.Current.Shutdown();        }        base.OnStartup(e);    }          }