Launch a single application instance

I have a Windows application (C #) and I need to configure it to run one instance from the application at a time. This means that one user clicked the .exe file and the application started, and the user did not close the first instance of the application that is running, and he needs to start the next instance so that it looks first and does not open a new one.

can anyone help me how to do this?

early

+4
source share
7 answers

I often solve this by checking other processes with the same name. The advantage / disadvantage is that you (or the user) can “backtrack” the check by renaming exe. If you do not want you to probably use the returned Process object.

string procName = Process.GetCurrentProcess().ProcessName; if (Process.GetProcessesByName(procName).Length == 1) { ...code here... } 

It depends on your need, I think it is convenient for bypassing the recompilation witout check (this is a server process that sometimes starts as a service).

+10
source

The VB.Net team has already implemented the solution. You will need to depend on Microsoft.VisualBasic.dll, but if that does not bother you, then this is a good IMHO solution. See End of Next Article: Single-Copy Applications

Here are the relevant parts of the article:

1) Add a link to Microsoft.VisualBasic.dll 2) Add the following class to your project.

 public class SingleInstanceApplication : WindowsFormsApplicationBase { private SingleInstanceApplication() { base.IsSingleInstance = true; } public static void Run(Form f, StartupNextInstanceEventHandler startupHandler) { SingleInstanceApplication app = new SingleInstanceApplication(); app.MainForm = f; app.StartupNextInstance += startupHandler; app.Run(Environment.GetCommandLineArgs()); } } 

Open Program.cs and add the following statement:

 using Microsoft.VisualBasic.ApplicationServices; 

Change the class as follows:

 static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); SingleInstanceApplication.Run(new Form1(), StartupNextInstanceEventHandler); } public static void StartupNextInstanceEventHandler(object sender, StartupNextInstanceEventArgs e) { MessageBox.Show("New instance"); } } 
+4
source

Edit: after the question has been changed to include C #. My answer only works for vb.net application

check the Make single application instance box to prevent users from running multiple instances of your application. The default value for this flag is cleared, allowing you to run multiple instances of the application.

You can do this from Project -> Properties -> Application tab

A source

+1
source

We had exactly the same problem. We tried the process approach, but this fails if the user does not have the right to read information about other processes, that is, non-admins. Therefore, we have implemented the solution below.

We are mainly trying to open the file for exclusive reading. If this fails (because the anohter instance already did this), we get an exception and can exit the application.

  bool haveLock = false; try { lockStream = new System.IO.FileStream(pathToTempFile,System.IO.FileMode.Create,System.IO.FileAccess.ReadWrite,System.IO.FileShare.None); haveLock = true; } catch(Exception) { System.Console.WriteLine("Failed to acquire lock. "); } if(!haveLock) { Inka.Controls.Dialoge.InkaInfoBox diag = new Inka.Controls.Dialoge.InkaInfoBox("App has been started already"); diag.Size = new Size(diag.Size.Width + 40, diag.Size.Height + 20); diag.ShowDialog(); Application.Exit(); } 
+1
source

Assuming you are using C #

  static Mutex mx; const string singleInstance = @"MU.Mutex"; /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { try { System.Threading.Mutex.OpenExisting(singleInstance); MessageBox.Show("already exist instance"); return; } catch(WaitHandleCannotBeOpenedException) { mx = new System.Threading.Mutex(true, singleInstance); } Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); } 
0
source

I would use Mutex for this scenario. Alternatively, a Semaphore will also work (but a Mutex seems more appropriate).

Here is my example (from a WPF application, but the same principles should apply to other types of projects):

 public partial class App : Application { const string AppId = "MY APP ID FOR THE MUTEX"; static Mutex mutex = new Mutex(false, AppId); static bool mutexAccessed = false; protected override void OnStartup(StartupEventArgs e) { try { if (mutex.WaitOne(0)) mutexAccessed = true; } catch (AbandonedMutexException) { //handle the rare case of an abandoned mutex //in the case of my app this isn't a problem, and I can just continue mutexAccessed = true; } if (mutexAccessed) base.OnStartup(e); else Shutdown(); } protected override void OnExit(ExitEventArgs e) { if (mutexAccessed) mutex?.ReleaseMutex(); mutex?.Dispose(); mutex = null; base.OnExit(e); } } 
0
source

I found this code , it works!

  /// <summary> /// The main entry point for the application. /// Limit an app.to one instance /// </summary> [STAThread] static void Main() { //Mutex to make sure that your application isn't already running. Mutex mutex = new System.Threading.Mutex(false, "MyUniqueMutexName"); try { if (mutex.WaitOne(0, false)) { // Run the application Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } else { MessageBox.Show("An instance of the application is already running.", "An Application Is Running", MessageBoxButtons.OK, MessageBoxIcon.Information); } } catch (Exception ex) { MessageBox.Show(ex.Message, "Application Error 'MyUniqueMutexName'", MessageBoxButtons.OK, MessageBoxIcon.Information); } finally { if (mutex != null) { mutex.Close(); mutex = null; } } } 
0
source

All Articles