This is the code I implemented so far to create a single instance WPF application:
#region Using Directives
using System;
using System.Globalization;
using S
to prevent a second instance (and signal the existing),
it could be done like this (this for an WPF app (see ref to App()), but works on WinForms as well):
public partial class App : Application
{
public App()
{
// initiate it. Call it first.
preventSecond();
}
private const string UniqueEventName = "{GENERATE-YOUR-OWN-GUID}";
private void preventSecond()
{
try
{
EventWaitHandle.OpenExisting(UniqueEventName); // check if it exists
this.Shutdown();
}
catch (WaitHandleCannotBeOpenedException)
{
new EventWaitHandle(false, EventResetMode.AutoReset, UniqueEventName); // register
}
}
}
Second version: above plus signaling the other instance to show the window (change the MainWindow part for WinForms):
public partial class App : Application
{
public App()
{
// initiate it. Call it first.
//preventSecond();
SingleInstanceWatcher();
}
private const string UniqueEventName = "{GENERATE-YOUR-OWN-GUID}";
private EventWaitHandle eventWaitHandle;
/// prevent a second instance and signal it to bring its mainwindow to foreground
///
private void SingleInstanceWatcher()
{
// check if it is already open.
try
{
// try to open it - if another instance is running, it will exist , if not it will throw
this.eventWaitHandle = EventWaitHandle.OpenExisting(UniqueEventName);
// Notify other instance so it could bring itself to foreground.
this.eventWaitHandle.Set();
// Terminate this instance.
this.Shutdown();
}
catch (WaitHandleCannotBeOpenedException)
{
// listen to a new event (this app instance will be the new "master")
this.eventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, UniqueEventName);
}
// if this instance gets the signal to show the main window
new Task(() =>
{
while (this.eventWaitHandle.WaitOne())
{
Current.Dispatcher.BeginInvoke((Action)(() =>
{
// could be set or removed anytime
if (!Current.MainWindow.Equals(null))
{
var mw = Current.MainWindow;
if (mw.WindowState == WindowState.Minimized || mw.Visibility != Visibility.Visible)
{
mw.Show();
mw.WindowState = WindowState.Normal;
}
// According to some sources these steps are required to be sure it went to foreground.
mw.Activate();
mw.Topmost = true;
mw.Topmost = false;
mw.Focus();
}
}));
}
})
.Start();
}
}
This code as a drop in class, will be @ Selfcontained-C-Sharp-WPF-compatible-utility-classes / Utils.SingleInstance.cs