Ensuring only one application instance

43,821

Solution 1

GetProcessesByName is slow way of checking if another instance is running. The fastest and elegant method is using mutex:

[STAThread]
    static void Main()
    {
        bool result;
        var mutex = new System.Threading.Mutex(true, "UniqueAppId", out result);

        if (!result)
        {
            MessageBox.Show("Another instance is already running.");
            return;
        }

        Application.Run(new Form1());

        GC.KeepAlive(mutex);                // mutex shouldn't be released - important line
    }

Please also bear in mind that the code you presented is not the best approach. As it was advised in one of comments calling DoEvents() in a loop is not the best idea.

Solution 2

static class Program
{
    // Mutex can be made static so that GC doesn't recycle
    // same effect with GC.KeepAlive(mutex) at the end of main
    static Mutex mutex = new Mutex(false, "some-unique-id");

    [STAThread]
    static void Main()
    {
        // if you like to wait a few seconds in case that the instance is just 
        // shutting down
        if (!mutex.WaitOne(TimeSpan.FromSeconds(2), false))
        {
            MessageBox.Show("Application already started!", "", MessageBoxButtons.OK);
            return;
        }

        try
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
        finally { mutex.ReleaseMutex(); } // I find this more explicit
    }
}

One note about the some-unique-id -> this should be unique on the machine, so use something like your company name / application name.

Edit:

http://sanity-free.org/143/csharp_dotnet_single_instance_application.html

Share:
43,821

Related videos on Youtube

GurdeepS
Author by

GurdeepS

Updated on July 09, 2022

Comments

  • GurdeepS
    GurdeepS almost 2 years

    Possible Duplicate:
    What is the correct way to create a single instance application?

    I have a Winforms app, which launches a splash screen via the following code:

    Hide();
            bool done = false;
            // Below is a closure which will work with outer variables.
            ThreadPool.QueueUserWorkItem(x =>
                                      {
                                          using (var splashForm = new SplashScreen())
                                          {
                                              splashForm.Show();
                                              while (!done)
                                                  Application.DoEvents();
                                              splashForm.Close();
                                          }
                                      });
    
            Thread.Sleep(3000);
            done = true;
    

    The above is in the main form's codebehind and called from the load event handler.

    However, how can I ensure that only one instance of the application will load at a time? In the load event handler of the main form, I could check if the process list is on the system (via GetProcessesByName(...)), but is there a better method?

    Using .NET 3.5.

    • SLaks
      SLaks almost 13 years
      You should call Application.Run(splashForm) instead of a DoEvents() loop.
  • monstr
    monstr about 10 years
    GC.KeepAlive(mutex); - doesn't work for me by some reasons. I was forsed to use private static mutex;
  • Alex B.
    Alex B. over 9 years
    I may be wrong, but shouldn't 'GC.KeepAlive(mutex);' line be before 'Application.Run(new Form1());'? 'Application.Run()' method starts the program's message loop and does not return until 'Form1' is closed.
  • michalczerwinski
    michalczerwinski about 9 years
    @AlexB.: no, this is on purpose. The goal is to prevent mutex from being released, which can occured when a new form is opened and Form1 is closed. Before Form1 is closed there is no risk of mutex being released
  • bh_earth0
    bh_earth0 about 8 years
    in if block, putting "application.exit()" instead of "return ", works form me, but i put the mutex check in the form1's form_load .
  • qakmak
    qakmak about 8 years
    Why some people recommend use mutex.ReleaseMutex(), what's the difference between GC.KeepAlive(mutex) ?