Introduction
This article describes a component that makes a Winform application single instance.
Background
'Why another Single Instance implementation', some of you might ask. Well the short answer is that I started out with the implementation from Michael Potter but ran into problems when I tried to use it with an application that was minimized to the explorer status area. The solution presented here uses a Mutex to detect an already running instance and remoting to signal the starting of a new instance.
Using the code
To use the component, is has to be added to the toolbox first. The component can then be dropped onto a form where it will show up in the component tray.
The image below shows the properties (events) for a SingleInstance
component.

For some applications, it may be useful to install an InstanceActivate
handler. The handler gets called each time a second instance is being started. As an additional benefit, the event arguments also contain the command line arguments that have been passed to the second instance.
private void singleInstance1_InstanceActivate(object sender,
rr.Windows.Forms.SingleInstance.InstanceActivateEventArgs e)
{
foreach (string s in e.CommandLineArgs)
{
Debug.WriteLine(s);
}
}
The default behavior of the component after InstanceActivate
is to bring the first instance to the foreground. To prevent that, the Cancel
property must be set to true
.
e.Cancel=true;
Points of interest
While testing the component on XP with a different user account, while one instance of the test application was already running under my normal account, I started getting a Only one usage of each socket address (protocol/network address/port) is normally permitted
error. I started to realize that using a fixed port number would not work, so I provided 0 for the channel to get a free port number.
TcpChannel chan = new TcpChannel(0);
But now the problem was that the client could not connect to the server because, it didn't know the port number the server was listening on. After considering several different approaches I finally decided to use a registry key in the HKEY_CURRENT_USER
hive.
Another implementation detail that makes me a bit uneasy is that I use,
Process.GetCurrentProcess().Kill();
in the middle of the form's InitializeComponent
function to terminate the second instance. Implementations that require code to be run before the process is being killed may hook the InstanceShutdown
event.
History
- Initial Release: 4. August 2003 (Version 1.1)