8

I tried to do it this way:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Diagnostics;
using DannyGeneral;

namespace mws
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            try
            {
                if (IsApplicationAlreadyRunning() == true)
                {
                    MessageBox.Show("The application is already running");
                }
                else
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new Form1());
                }
            }
            catch (Exception err)
            {
                Logger.Write("error " + err.ToString());
            }
        }
        static bool IsApplicationAlreadyRunning()
        {
            string proc = Process.GetCurrentProcess().ProcessName;
            Process[] processes = Process.GetProcessesByName(proc);
            if (processes.Length > 1)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}

But I'm getting some problems.

First, when I'm loading my project in Visual Studio and then running my program it's detecting the vshost.exe file of my project for example: My project.vshost

And I want that it will detect if my program is running only when I'm running the program only if it find the .exe for example: My project.exe not the vshost.

Phoenix
  • 1,045
  • 1
  • 14
  • 22
Helem Shoshi
  • 239
  • 1
  • 3
  • 14

2 Answers2

24

Have a look at using a mutex.

static class Program {
    static Mutex mutex = new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}");
    [STAThread]
    static void Main() {
        if(mutex.WaitOne(TimeSpan.Zero, true)) {
            try
            {
             Application.EnableVisualStyles();
             Application.SetCompatibleTextRenderingDefault(false);
             Application.Run(new Form1());
            }
            finally
            {
             mutex.ReleaseMutex();
            }
        } else {
            MessageBox.Show("only one instance at a time");
        }
    }
}

If our app is running, WaitOne will return false, and you'll get a message box.

As @Damien_The_Unbeliever pointed out correctly, you should change the Guid of the mutex for each application you write!

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

flayn
  • 5,272
  • 4
  • 48
  • 69
  • 4
    Might be worth adding an obnoxious comment above and below the GUID pointing out that a new one should be generated for each application that you place this code in. Otherwise, once several people have C&Ped this code into their projects and not thought about it, you have a *class* of programs of which only one instance can run at any time. – Damien_The_Unbeliever Feb 02 '15 at 10:16
  • 2
    @Damien_The_Unbeliever Or better use application name itself. `Mutex mutex = new Mutex(true, Assembly.GetEntryAssembly().GetName().Name, out createdNew);` – Sriram Sakthivel Feb 02 '15 at 10:19
  • Also see this: http://stackoverflow.com/questions/229565/what-is-a-good-pattern-for-using-a-global-mutex-in-c – Matthew Watson Feb 02 '15 at 10:20
  • 1
    @Siriam - that can have its own issues if multiple people decide to use the same name for separate programs. The GUID idea, in and of itself, isn't a bad one, since you only have collisions if a) Someone's deliberately trying to cause a collision or b) The code is copied and pasted from somewhere and people aren't aware that it needs editing. – Damien_The_Unbeliever Feb 02 '15 at 10:28
  • It does not work with the editor but works on compiled mode very well. – Ismail Gunes Oct 18 '15 at 11:12
3

Could you please try below snippet?

private static void Main(string[] args)
    {

        if (IsApplicationAlreadyRunning())
        {
            Console.Write("The application is already running");
        }
        else
        {
            Console.Write("The application is not running");
        }
        Console.Read();
    }

     static bool IsApplicationAlreadyRunning()
    {
        return Process.GetProcesses().Count(p => p.ProcessName.Contains(Assembly.GetExecutingAssembly().FullName.Split(',')[0]) && !p.Modules[0].FileName.Contains("vshost")) > 1;
    }
Ashish Sapkale
  • 540
  • 2
  • 13