?
Solved

Restricting C# Application to one instance

Posted on 2011-09-12
7
Medium Priority
?
1,391 Views
Last Modified: 2012-06-27

Hi,

I would like to restrict my C# Winforms application to one instance per PC only?

Is there an elegant way of doing this? Programmatic or other.

Thanks in advance.

0
Comment
Question by:Ibs
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
7 Comments
 
LVL 15

Assisted Solution

by:Navneet
Navneet earned 200 total points
ID: 36521706
Hi!

check this!
http://www.ai.uga.edu/mc/SingleInstance.html


Best way is to check enumerated the running process and
check whether your process is running  if found then there is already one instance running  else
run your startup form

Thanks!
0
 
LVL 15

Expert Comment

by:Navneet
ID: 36521713
0
 
LVL 15

Expert Comment

by:Russell_Venable
ID: 36529483

This is essentially what I use. This page shows a proper example of usage.

private Mutex mutex;
private string mutexName = "Todo3.0Mutex";

http://joelbennett.wordpress.com/2007/04/14/using-a-mutex-to-prevent-multiple-copies-of-an-application-from-runningc/

 

 
0
Get your Conversational Ransomware Defense e‑book

This e-book gives you an insight into the ransomware threat and reviews the fundamentals of top-notch ransomware preparedness and recovery. To help you protect yourself and your organization. The initial infection may be inevitable, so the best protection is to be fully prepared.

 
LVL 1

Assisted Solution

by:Temizh
Temizh earned 600 total points
ID: 36532280
You should mutex and process check together:

1: Mutex:
         public From1()
        {
            System.Threading.Mutex mutex = new System.Threading.Mutex(false, "Local\\MyAppName", out firstInstance);
            if (firstInstance && InstanceRunning())
            {
                InitializeComponent();
                Cursor.Hide();
            }
            else
            {
                this.Close();
            }
        }

Open in new window


2. process name:

private bool InstanceRunning
        {
            get
            {
                string strProcessName = System.Diagnostics.Process.GetCurrentProcess().ProcessName;

                System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName(strProcessName);

                return (processes.Length > 1);

            }
        }

Open in new window


Mutex checks thread which helps you by prevent to run more instances of a windows form running on same process, the second one prevents to run different processes. together they prevent program to run more than one instance.
0
 
LVL 12

Expert Comment

by:starlite551
ID: 36532386
Here is a very useful link using Mutex Class :

http://iridescence.no/post/CreatingaSingleInstanceApplicationinC.aspx
0
 
LVL 12

Accepted Solution

by:
starlite551 earned 1200 total points
ID: 36532396
Use this code :
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.Reflection;
using System.IO;

namespace SingleInstance
{
	/// <summary>
	/// Summary description for SingleApp.
	/// </summary>
	public class SingleApplication
	{
		public SingleApplication()
		{

		}
		/// <summary>
		/// Imports 
		/// </summary>
	
		[DllImport("user32.dll")]
		private static extern int ShowWindow(IntPtr hWnd, int nCmdShow);

		[DllImport("user32.dll")]
		private static extern int SetForegroundWindow(IntPtr hWnd);

		[DllImport("user32.dll")]
		private static extern int IsIconic(IntPtr hWnd);

		/// <summary>
		/// GetCurrentInstanceWindowHandle
		/// </summary>
		/// <returns></returns>
		private static IntPtr GetCurrentInstanceWindowHandle()
		{    
			IntPtr hWnd = IntPtr.Zero;
			Process process = Process.GetCurrentProcess();
			Process[] processes = Process.GetProcessesByName(process.ProcessName);
			foreach(Process _process in processes)
			{
				// Get the first instance that is not this instance, has the
				// same process name and was started from the same file name
				// and location. Also check that the process has a valid
				// window handle in this session to filter out other user's
				// processes.
				if (_process.Id != process.Id &&
					_process.MainModule.FileName == process.MainModule.FileName &&
					_process.MainWindowHandle != IntPtr.Zero)    
				{
					hWnd = _process.MainWindowHandle;
					break;
				}
			}
			return hWnd;
		}
		/// <summary>
		/// SwitchToCurrentInstance
		/// </summary>
		private static void SwitchToCurrentInstance()
		{    
			IntPtr hWnd = GetCurrentInstanceWindowHandle();
			if (hWnd != IntPtr.Zero)    
			{    
				// Restore window if minimised. Do not restore if already in
				// normal or maximised window state, since we don't want to
				// change the current state of the window.
				if (IsIconic(hWnd) != 0)
				{
					ShowWindow(hWnd, SW_RESTORE);
				}

				// Set foreground window.
				SetForegroundWindow(hWnd);
			}
		}

		/// <summary>
		/// Execute a form base application if another instance already running on
		/// the system activate previous one
		/// </summary>
		/// <param name="frmMain">main form</param>
		/// <returns>true if no previous instance is running</returns>
		public static bool Run(System.Windows.Forms.Form frmMain)
		{
			if(IsAlreadyRunning())
			{
				//set focus on previously running app
				SwitchToCurrentInstance();
				return false;
			}
			Application.Run(frmMain);
			return true;
		}

		/// <summary>
		/// for console base application
		/// </summary>
		/// <returns></returns>
		public static bool Run()
		{
			if(IsAlreadyRunning()) 
			{
				return false;
			}
			return true;
		}

		/// <summary>
		/// check if given exe alread running or not
		/// </summary>
		/// <returns>returns true if already running</returns>
		private static bool IsAlreadyRunning()
		{
			string strLoc = Assembly.GetExecutingAssembly().Location;
			FileSystemInfo fileInfo = new FileInfo(strLoc);
			string sExeName = fileInfo.Name;
			bool bCreatedNew;

			mutex = new Mutex(true, "Global\\"+sExeName, out bCreatedNew);
			if (bCreatedNew)
				mutex.ReleaseMutex();

			return !bCreatedNew;
		}
		
		static Mutex mutex;
		const int SW_RESTORE = 9;
	}
}

Open in new window

0
 

Author Comment

by:Ibs
ID: 36908787

Hi All, several good options here, I am currently trying these out.
Thanks for all your suggestions.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Suggested Courses

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question