What Is the Correct Way to Create a Single-Instance Wpf Application

What is the correct way to create a single-instance WPF application?

Here is a very good article regarding the Mutex solution. The approach described by the article is advantageous for two reasons.

First, it does not require a dependency on the Microsoft.VisualBasic assembly. If my project already had a dependency on that assembly, I would probably advocate using the approach shown in another answer. But as it is, I do not use the Microsoft.VisualBasic assembly, and I'd rather not add an unnecessary dependency to my project.

Second, the article shows how to bring the existing instance of the application to the foreground when the user tries to start another instance. That's a very nice touch that the other Mutex solutions described here do not address.


UPDATE

As of 8/1/2014, the article I linked to above is still active, but the blog hasn't been updated in a while. That makes me worry that eventually it might disappear, and with it, the advocated solution. I'm reproducing the content of the article here for posterity. The words belong solely to the blog owner at Sanity Free Coding.

Today I wanted to refactor some code that prohibited my application
from running multiple instances of itself.

Previously I had use System.Diagnostics.Process to search for an
instance of my myapp.exe in the process list. While this works, it
brings on a lot of overhead, and I wanted something cleaner.

Knowing that I could use a mutex for this (but never having done it
before) I set out to cut down my code and simplify my life.

In the class of my application main I created a static named Mutex:

static class Program
{
static Mutex mutex = new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}");
[STAThread]
...
}

Having a named mutex allows us to stack synchronization across
multiple threads and processes which is just the magic I'm looking
for.

Mutex.WaitOne has an overload that specifies an amount of time for us
to wait. Since we're not actually wanting to synchronizing our code
(more just check if it is currently in use) we use the overload with
two parameters: Mutex.WaitOne(Timespan timeout, bool exitContext).
Wait one returns true if it is able to enter, and false if it wasn't.
In this case, we don't want to wait at all; If our mutex is being
used, skip it, and move on, so we pass in TimeSpan.Zero (wait 0
milliseconds), and set the exitContext to true so we can exit the
synchronization context before we try to aquire a lock on it. Using
this, we wrap our Application.Run code inside something like this:

static class Program
{
static Mutex mutex = new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}");
[STAThread]
static void Main() {
if(mutex.WaitOne(TimeSpan.Zero, true)) {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
mutex.ReleaseMutex();
} else {
MessageBox.Show("only one instance at a time");
}
}
}

So, if our app is running, WaitOne will return false, and we'll get a
message box.

Instead of showing a message box, I opted to utilize a little Win32 to
notify my running instance that someone forgot that it was already
running (by bringing itself to the top of all the other windows). To
achieve this I used PostMessage to broadcast a custom message to every
window (the custom message was registered with RegisterWindowMessage
by my running application, which means only my application knows what
it is) then my second instance exits. The running application instance
would receive that notification and process it. In order to do that, I
overrode WndProc in my main form and listened for my custom
notification. When I received that notification I set the form's
TopMost property to true to bring it up on top.

Here is what I ended up with:

  • Program.cs
static class Program
{
static Mutex mutex = new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}");
[STAThread]
static void Main() {
if(mutex.WaitOne(TimeSpan.Zero, true)) {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
mutex.ReleaseMutex();
} else {
// send our Win32 message to make the currently running instance
// jump on top of all the other windows
NativeMethods.PostMessage(
(IntPtr)NativeMethods.HWND_BROADCAST,
NativeMethods.WM_SHOWME,
IntPtr.Zero,
IntPtr.Zero);
}
}
}
  • NativeMethods.cs
// this class just wraps some Win32 stuff that we're going to use
internal class NativeMethods
{
public const int HWND_BROADCAST = 0xffff;
public static readonly int WM_SHOWME = RegisterWindowMessage("WM_SHOWME");
[DllImport("user32")]
public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);
[DllImport("user32")]
public static extern int RegisterWindowMessage(string message);
}
  • Form1.cs (front side partial)
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
protected override void WndProc(ref Message m)
{
if(m.Msg == NativeMethods.WM_SHOWME) {
ShowMe();
}
base.WndProc(ref m);
}
private void ShowMe()
{
if(WindowState == FormWindowState.Minimized) {
WindowState = FormWindowState.Normal;
}
// get our current "TopMost" value (ours will always be false though)
bool top = TopMost;
// make our form jump to the top of everything
TopMost = true;
// set it back to whatever it was
TopMost = top;
}
}

WPF Single Instance Best Practices

1) It looks like a standard Dispose implementation to me. It is not really necessary (see point 6) but it does not do any harm. (Cleanup on closing it's a bit like cleaning the house before burning it down, IMHO, but opinions on the matter differs..)

Anyway, why not using "Dispose" as the name of the cleanup method, even if it does not get called directly? You could have called it "Cleanup", but remember you also write code for humans, and Dispose looks familiar and anyone on .NET understands what is it for. So, go for "Dispose".

2) I have always seen m_Mutex = new Mutex(false, mutexName); I think it's more a convention that a technical advantage, however.

3) From MSDN:

If the message is successfully registered, the return value is a message identifier in the range 0xC000 through 0xFFFF.

So I would not worry. Usually, for this class of functions, UInt is not used for "it does not fit in Int, let's use UInt so we have something more" but to clarify a contract "function never returns a negative value".

4) I would avoid calling it if you will shutdown, same reason as #1

5) There are a couple of ways of doing it. The easiest way in Win32 is simply to have the second instance make the call to SetForegroundWindow (Look here: http://blogs.msdn.com/b/oldnewthing/archive/2009/02/20/9435239.aspx); however, I don't know if there is an equivalent WPF functionality or if you need to PInvoke it.

6)

For example... what happens if my application crashes between OnStartup and OnExit?

It's OK: when a process terminates, all handles owned by the process are released; the mutex is released as well.

In short, my recommendations:

  • I would used an approach based on named synchronization objects: it is the more established on the windows platform(s). (Be careful when considering a multi-user system, like terminal server! Name the synchronization object as a combination of, maybe, user name/SID and application name)
  • Use the Windows API to raise the previous instance (see my link at point #5), or the WPF equivalent.
  • You probably do not have to worry about crashes (kernel will decrease the ref counter for the kernel object for you; do a little test anyway), BUT If I may suggest an improvement: what if your first application instance does not crash but hangs? (Happens with Firefox.. I'm sure it happened to you too! No window, ff process, you cannot open a new one). In that case it may be good to combine another technique or two, to a) test if the application/window responds; b) find the hung instance and terminate it

For example, you can use your technique (trying to send/post a message to the window - if does not answer back it is stuck), plus MSK technique, to find and terminate the old process. Then start normally.

How to create single instance WPF Application that restores the open window when an attempt is made to open another instance?

You're looking for the Mutex Class. It's pretty complicated, but luckily the Singleton Pattern has been widely discussed. There are several good articles on it, but you can find a good implementation of it in the C# .NET Single Instance Application page on the Sanity Free Coding website. From the linked page:

static class Program {
static Mutex mutex = new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}");
[STAThread]
static void Main() {
if(mutex.WaitOne(TimeSpan.Zero, true)) {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
mutex.ReleaseMutex();
} else {
MessageBox.Show("only one instance at a time");
}
}
}

Now you're probably wondering how to have a Main method in a WPF Application, right? Well there's a few things that you have to do, but it's not difficult. See the Writing a custom Main() method for WPF applications article which explains this in detail. From that article:

You basically need to change the application’s build action from “Application Definition” to “Page”, create a constructor that calls “InitializeComponent”, and write your Main() by eventually calling one of the application’s “Run” method overloads. ... Don’t forget, also, to remove the “StartupUri” from the App.xaml, otherwise another copy of window will show up (unless you get an error because the URI points to a non existing XAML resource).

So by amalgamating these two resources, we can see that your App.xaml.cs file should look something like this:

public partial class App : Application
{
private static Mutex mutex = new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}");
private static MainWindow mainWindow = null;

App()
{
InitializeComponent();
}

[STAThread]
static void Main()
{
if(mutex.WaitOne(TimeSpan.Zero, true))
{
App app = new App();
mainWindow = new MainWindow();
app.Run(mainWindow);
mutex.ReleaseMutex();
}
else
{
mainWindow.WindowState = WindowState.Normal;
}
}
}

WPF, how to make a single instance and shows the MainWindow when another instance is launched in c#

I created a sample WPF app and only changed the App.xaml.cs file. If the single-instance window is already open, this code will find any process that matches the name of the current process, and if that process has a window, shows it:

public partial class App : Application
{
// signals to restore the window to its normal state
private const int SW_SHOWNORMAL = 1;

// create the mutex
private const string MUTEXNAME = "FirstInstance";
private readonly Mutex _mutex = new Mutex(true, MUTEXNAME);

public App()
{
if (!_mutex.WaitOne(TimeSpan.Zero))
{
ShowExistingWindow();
Shutdown();
}
}

[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);

[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

// shows the window of the single-instance that is already open
private void ShowExistingWindow()
{
var currentProcess = Process.GetCurrentProcess();
var processes = Process.GetProcessesByName(currentProcess.ProcessName);
foreach (var process in processes)
{
// the single-instance already open should have a MainWindowHandle
if (process.MainWindowHandle != IntPtr.Zero)
{
// restores the window in case it was minimized
ShowWindow(process.MainWindowHandle, SW_SHOWNORMAL);

// brings the window to the foreground
SetForegroundWindow(process.MainWindowHandle);

return;
}
}
}
}

FYI, this does not work in debug mode because .vshost becomes part of the process name. If you need it to work in debug mode, you need to iterate through all processes instead of calling Process.GetProcessesByName.

What is the correct way to create a single-instance WPF application?

Here is a very good article regarding the Mutex solution. The approach described by the article is advantageous for two reasons.

First, it does not require a dependency on the Microsoft.VisualBasic assembly. If my project already had a dependency on that assembly, I would probably advocate using the approach shown in another answer. But as it is, I do not use the Microsoft.VisualBasic assembly, and I'd rather not add an unnecessary dependency to my project.

Second, the article shows how to bring the existing instance of the application to the foreground when the user tries to start another instance. That's a very nice touch that the other Mutex solutions described here do not address.


UPDATE

As of 8/1/2014, the article I linked to above is still active, but the blog hasn't been updated in a while. That makes me worry that eventually it might disappear, and with it, the advocated solution. I'm reproducing the content of the article here for posterity. The words belong solely to the blog owner at Sanity Free Coding.

Today I wanted to refactor some code that prohibited my application
from running multiple instances of itself.

Previously I had use System.Diagnostics.Process to search for an
instance of my myapp.exe in the process list. While this works, it
brings on a lot of overhead, and I wanted something cleaner.

Knowing that I could use a mutex for this (but never having done it
before) I set out to cut down my code and simplify my life.

In the class of my application main I created a static named Mutex:

static class Program
{
static Mutex mutex = new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}");
[STAThread]
...
}

Having a named mutex allows us to stack synchronization across
multiple threads and processes which is just the magic I'm looking
for.

Mutex.WaitOne has an overload that specifies an amount of time for us
to wait. Since we're not actually wanting to synchronizing our code
(more just check if it is currently in use) we use the overload with
two parameters: Mutex.WaitOne(Timespan timeout, bool exitContext).
Wait one returns true if it is able to enter, and false if it wasn't.
In this case, we don't want to wait at all; If our mutex is being
used, skip it, and move on, so we pass in TimeSpan.Zero (wait 0
milliseconds), and set the exitContext to true so we can exit the
synchronization context before we try to aquire a lock on it. Using
this, we wrap our Application.Run code inside something like this:

static class Program
{
static Mutex mutex = new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}");
[STAThread]
static void Main() {
if(mutex.WaitOne(TimeSpan.Zero, true)) {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
mutex.ReleaseMutex();
} else {
MessageBox.Show("only one instance at a time");
}
}
}

So, if our app is running, WaitOne will return false, and we'll get a
message box.

Instead of showing a message box, I opted to utilize a little Win32 to
notify my running instance that someone forgot that it was already
running (by bringing itself to the top of all the other windows). To
achieve this I used PostMessage to broadcast a custom message to every
window (the custom message was registered with RegisterWindowMessage
by my running application, which means only my application knows what
it is) then my second instance exits. The running application instance
would receive that notification and process it. In order to do that, I
overrode WndProc in my main form and listened for my custom
notification. When I received that notification I set the form's
TopMost property to true to bring it up on top.

Here is what I ended up with:

  • Program.cs
static class Program
{
static Mutex mutex = new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}");
[STAThread]
static void Main() {
if(mutex.WaitOne(TimeSpan.Zero, true)) {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
mutex.ReleaseMutex();
} else {
// send our Win32 message to make the currently running instance
// jump on top of all the other windows
NativeMethods.PostMessage(
(IntPtr)NativeMethods.HWND_BROADCAST,
NativeMethods.WM_SHOWME,
IntPtr.Zero,
IntPtr.Zero);
}
}
}
  • NativeMethods.cs
// this class just wraps some Win32 stuff that we're going to use
internal class NativeMethods
{
public const int HWND_BROADCAST = 0xffff;
public static readonly int WM_SHOWME = RegisterWindowMessage("WM_SHOWME");
[DllImport("user32")]
public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);
[DllImport("user32")]
public static extern int RegisterWindowMessage(string message);
}
  • Form1.cs (front side partial)
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
protected override void WndProc(ref Message m)
{
if(m.Msg == NativeMethods.WM_SHOWME) {
ShowMe();
}
base.WndProc(ref m);
}
private void ShowMe()
{
if(WindowState == FormWindowState.Minimized) {
WindowState = FormWindowState.Normal;
}
// get our current "TopMost" value (ours will always be false though)
bool top = TopMost;
// make our form jump to the top of everything
TopMost = true;
// set it back to whatever it was
TopMost = top;
}
}

What is the best way to make a single instance application in .net?

You can use a Mutex.

bool firstInstance = true;
using (Mutex mutex = new Mutex(true, "MyApplicationName", out firstInstance))
{
if (firstInstance)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
else
{
// Another instance loaded
}
}

How to generalize code to allow only one instance per Window in WPF application

The solution was provided by @Ben Bancroft in his example here:


OnlyOneOfEachTypeOfWindow-Example

As @NPras told me, it uses the Factory-Pattern to solve the problem, mainly with the class here:

public static class WindowManager
{
public static T GetWindow<T>()
{
var t = Application.Current.Windows.OfType<T>().FirstOrDefault();
if (t == null)
{
t = (T)Activator.CreateInstance(typeof(T));
}
return t;
}

public static T CreateOrFocusWindow<T>()
{
var t = GetWindow<T>();
if (t is Window)
{
var window = t as Window;
if (window.Visibility != Visibility.Visible)
window.Show();
if (window.WindowState == WindowState.Minimized)
window.WindowState = WindowState.Normal;
window.Focus();
}
return t;
}
}

You can then use it like:

var window = WindowManager.CreateOrFocusWindow<Window1>();
var window = WindowManager.CreateOrFocusWindow<Window2>();

Thanks for the help!

Single instance WPF application using Caliburn.Micro

I use a named mutex in my main method and show a dialog if the mutex already exists.

Check this stack - WPF Single Instance Best Practices

Correct .NET way to implement a single instance application

When in doubt, always prefer an implementation that's included in the .NET framework. You can have high expectations that such an implementation is tested by hundreds of thousands of programmers, has been carefully reviewed for security and usability and will be maintained for years to come.

The mutex approach is an easy one to get going. It however suffers from a pretty severe security problem. A denial of service attack is very simple to get going, you cannot keep the name of your mutex a secret and anybody can trivially create a mutex with the same name and prevent your program from ever starting up.

The process name approach is deeply flawed for the same reason. There is no guarantee that a process name is unique. Not just easy to exploit but easily triggered by accident.

WindowsFormsApplicationBase has an image problem in the eyes of C# programmers. They choke at the namespace name and assume that their program will somehow be infected with vb-isms. That's nonsense, it is just a plain .NET class that's useable in any language.



Related Topics



Leave a reply



Submit