Extended WPF Application

Part 1: Single Instance-Application

Unlike Windows Forms, which have some of these, WPF does not have some features, such as:

This series of articles will explain how to add these features to a WPF application. This one is the first of this series. In this article, we will see how to make a WPF single-instance application.

Principle

A WPF application cannot be really single-instanced. To get this behavior, we need a workaround. The idea is to launch a first instance (hereafter called the server). The server is the instance which shows the windows of your application. It can receive arguments or not.

After the server has launched, an other process could have to call your application again with new arguments. So, we want the server to be able to handle these new ones again. However, as it has already been called by another process, we cannot call the Main method of the server again to do that. So, the idea is that the new instances, once the Main method had been called, will transfer their arguments to the server, which will handle they, and close theyselves right after.

Prerequisites

Packages (all available on NuGet)

To achieve this task, we will need the following packages:

Patterns used

We will use the following patterns and objects:

Make your project ready

Because we will need to override the Main window of the application, we need to remove the App.xaml file that is automatically generated by Visual Studio, as this file produces its own Main method when building the application. The set up that is made trough this file have to be done on the App.cs file.
As consequences, if your app has a default XAML resource dictionary, it have to be defined in its own file, and called with code-behind in the App.cs file.

The simplest way

In App.cs, add the following method:

[STAThread]
public static async Task Main(string[] args)
{

}

The simplest way to implement this single-instance pattern is to make the following operations:

  1. checking if the current instance received arguments. If not, it can start directly as the server instance if there is no server opened already or as a client one if there is a server opened already
  2. initializing a mutex in the Main method. It is it that checks whether a server is already opened
  3. if there is already a server opened, transfer all arguments to it using named pipes. Otherwise, open a server.

This is the simplest way, but it takes some time. This is why the WinCopies.IPCService.Extensions package will be helpful: all that code, from the mutex check to the transfer of the arguments, is already implemented in it. So, all we have to do is to call the StartInstanceAsync method of the ISingleInstanceApp interface. This is interface is implemented by the caller of that method, here the application in order to call that method from the Main method.

What if the application has different modes?

Let's consider a file manager. This kind of software has two main modes: the explorer one and the process handler one. If we have an application for each mode, they may appear at different positions in the task bar. So, we need a single application for each mode, but, also, each of these modes can have their own server. The solution is to have a base abstract class for the implementation of the ISingleInstanceApp interface, and split the code in the Main method to a method by feature and, also by mode for those for which this is applicable.

Sample

An advanced example of that is available at: ExtendedWPFApplication