[c#] Checking if my Windows application is running

How do I check if my C# Windows application is running ?

I know that I can check the process name but the name can be changed if the exe changes.

Is there any way to have a hash key or something to make my application unique?

This question is related to c# winforms

The answer is


Enter a guid in your assembly data. Add this guid to the registry. Enter a reg key where the application read it's own name and add the name as value there.

The other task watcher read the reg key and knows the app name.


you can simply use varialbles and one file to check for running your program. when open the file contain a value and when program closes changes this value to another one.


For my WPF application i've defined global app id and use semaphore to handle it.

public partial class App : Application
{      
    private const string AppId = "c1d3cdb1-51ad-4c3a-bdb2-686f7dd10155";

    //Passing name associates this sempahore system wide with this name
    private readonly Semaphore instancesAllowed = new Semaphore(1, 1, AppId);

    private bool WasRunning { set; get; }

    private void OnExit(object sender, ExitEventArgs e)
    {
        //Decrement the count if app was running
        if (this.WasRunning)
        {
            this.instancesAllowed.Release();
        }
    }

    private void OnStartup(object sender, StartupEventArgs e)
    {
        //See if application is already running on the system
        if (this.instancesAllowed.WaitOne(1000))
        {
            new MainWindow().Show();
            this.WasRunning = true;
            return;
        }

        //Display
        MessageBox.Show("An instance is already running");

        //Exit out otherwise
        this.Shutdown();
    }
}

The recommended way is to use a Mutex. You can check out a sample here : http://www.codeproject.com/KB/cs/singleinstance.aspx

In specific the code:


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

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

            return !bCreatedNew;
        }

you need a way to say that "i am running" from the app,

1) open a WCF ping service 2) write to registry/file on startup and delete on shutdown 3) create a Mutex

... i prefer the WCF part because you may not clean up file/registry correctly and Mutex seems to have its own issues


Checkout: What is a good pattern for using a Global Mutex in C#?

// unique id for global mutex - Global prefix means it is global to the machine
const string mutex_id = "Global\\{B1E7934A-F688-417f-8FCB-65C3985E9E27}";

static void Main(string[] args)
{
    using (var mutex = new Mutex(false, mutex_id))
    {
        // edited by Jeremy Wiebe to add example of setting up security for multi-user usage
        // edited by 'Marc' to work also on localized systems (don't use just "Everyone") 
        var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow);
        var securitySettings = new MutexSecurity();
        securitySettings.AddAccessRule(allowEveryoneRule);
        mutex.SetAccessControl(securitySettings);

        //edited by acidzombie24
        var hasHandle = false;
        try
        {
            try
            {
                // note, you may want to time out here instead of waiting forever
                //edited by acidzombie24
                //mutex.WaitOne(Timeout.Infinite, false);
                hasHandle = mutex.WaitOne(5000, false);
                if (hasHandle == false) return;//another instance exist
            }
            catch (AbandonedMutexException)
            {
                // Log the fact the mutex was abandoned in another process, it will still get aquired
            }

            // Perform your work here.
        }
        finally
        {
            //edit by acidzombie24, added if statemnet
            if (hasHandle)
                mutex.ReleaseMutex();
        }
    }
}

I really simplistic way I guess would be, for every exe that is running, you could create/open a file on disk in a known location (c:\temp) with a special name "yourapp.lock" and then just count how many of those there are.

A harder way, would be to open up some inter-process communication, or sockets, so with the process list you could interrogate each process to see if it was your application.


Mutex and Semaphore didn't work in my case (I tried them as suggested, but it didn't do the trick in the application I developed). The answer abramlimpin provided worked for me, after I made a slight modification.

This is how I got it working finally. First, I created some helper functions:

public static class Ext
{
   private static string AssemblyFileName(this Assembly myAssembly)
    {
        string strLoc = myAssembly.Location;
        FileSystemInfo fileInfo = new FileInfo(strLoc);
        string sExeName = fileInfo.Name;
        return sExeName;
    }

    private static int HowManyTimesIsProcessRunning(string name)
    {
        int count = 0;
        name = name.ToLowerInvariant().Trim().Replace(".exe", "");
        foreach (Process clsProcess in Process.GetProcesses())
        {
            var processName = clsProcess.ProcessName.ToLowerInvariant().Trim();
            // System.Diagnostics.Debug.WriteLine(processName);
            if (processName.Contains(name))
            {
                count++;
            };
        };
        return count;
    }

    public static int HowManyTimesIsAssemblyRunning(this Assembly myAssembly)
    {
        var fileName = AssemblyFileName(myAssembly);
        return HowManyTimesIsProcessRunning(fileName);
    }
}

Then, I added the following to the main method:

[STAThread]
static void Main()
{
    const string appName = "Name of your app";

    // Check number of instances running:
    // If more than 1 instance, cancel this one.
    // Additionally, if it is the 2nd invocation, show a message and exit.
    var numberOfAppInstances = Assembly.GetExecutingAssembly().HowManyTimesIsAssemblyRunning();
    if (numberOfAppInstances == 2)
    {
       MessageBox.Show("The application is already running!
        +"\nClick OK to close this dialog, then switch to the application by using WIN + TAB keys.",
        appName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
    };
    if (numberOfAppInstances >= 2)
    {
        return;
    };
}

If you invoke the application a 3rd, 4th ... time, it does not show the warning any more and just exits immediately.