Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Single application instance using Mutex and WCF named pipes

0.00/5 (No votes)
21 Mar 2011 1  
There are a lot of articles where people describes how to create single instance application, but their solutions don't cover all use cases, for example when main window is hidden in tray

Introduction  

There are a lot of articles where people describes how to create single instance application using one Mutex, but their doesn't cove all use cases, for example when main window is hidden in tray.   

Background  

I think everybody knows how to create a single instance application in C#, if no, try to google and you will find a lot of examples where people use Mutex and then SendNotifyMessage function. This way is good only in case when main application window is visible. If application main window is hidden, Process.MainWindowHandle always returns zero, it means that there is no window for process. Some time ago one guy on "stackoverflow" asked how to make  "single instance application"  when application is hidden in tray, of course  it's very simple to use Mutex again, but how to show window if we don't know it handle?! Here is my solution. I used WCF server or client depends if it's first instance or not. If first instance, I start server, otherwise run WCF client and notify already running instance about new one.  

If it's a first application instance:  

1. Start WCF named pipe server inside application(of course it can be any type of communication such as .NET Remoting, Win Sockets etc. but i decided to use WCF) 

2. and listen for messages   

If it's not a first application instance

1. Connect to server and notify it about new application instance 

2. Exit from application. 

It gives some benefits for example: application decides what to do when new instance has been started. 

 Using the code 

For cases described above i've developed small library.  The main class is 

ApplicationInstanceManager, it can either server or client. Here is interface of ApplicationInstanceManager 

ApplicationInstanceManager.png 

IsInstanceAlreadyRun  - returns true if one or more instances already running
StartServer() - should be invoked only in case if it first application instance 
NotifyAboutNewInstance() - notifies already running application about new application. 
NewApplicationInstanceLoaded - event occurs when some application instance calls  NotifyAboutNewInstance()

Summarizing all that I said above possible usage of ApplicationSingleInstance class can be: 

static class Program
{
	private static MainForm _mainForm;
	/// <summary>
	/// The main entry point for the application.
	/// </summary>
	[STAThread]
	static void Main()
	{
		using (ApplicationSingleInstance singleInstance = new ApplicationSingleInstance("MyApplication"))
		{
			singleInstance.NewApplicationInstanceLoaded += new EventHandler(OnNewApplicationInstanceLoaded);

			if (!singleInstance.IsInstanceAlreadyRun)
			{
				singleInstance.StartServer();
				Application.EnableVisualStyles();
				Application.SetCompatibleTextRenderingDefault(false);
				_mainForm = new MainForm();
				Application.Run(_mainForm);      
			}
			else
			{
				singleInstance.NotifyAboutNewInstance();
			}
		}
	}

	static void OnNewApplicationInstanceLoaded(object sender, EventArgs e)
	{
		Action setTopMost = () =>
			{
				_mainForm.Visible = true;
				_mainForm.TopMost = true;
			};

			if (_mainForm.InvokeRequired)
				_mainForm.Invoke(setTopMost);
			else
				setTopMost();
	}
}

I also create a wrapper around ApplicationSingleInstance that encapsulate all logic and allows to start only one instance, I named it SingleInstace. SingleInstance class has only one public method - Run and takes application key and "Form" in .ctor. Here is a possible usage of SingleInstance class. SingleInsnance glass guarantee that only one application instance can be started. 

 static class Program
	{
		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main()
		{
			using(SingleInstance singleInstance = new SingleInstance("MyApplication1", new Form()))
			{
				singleInstance.Run();
			}
		}
	} 

 It only covers cases when for WinForms project, but it will not be difficult to adapt this solution for WPF project.

 

Thank you for reading. 

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here