tags:

views:

402

answers:

3

I have a .NET application that I only allow to run a single process at a time of, however that app is used on Citrix boxes from time to time, and as such, can be run by multiple users on the same machine.

I want to check and make sure that the application is only running once per user session, because right now if user A is running the app, then user B gets the "App already in use" message, and should not.

This is what I have now that checks for the running process:

Process[] p = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName);
            if (p.Length > 1)
            {
#if !DEBUG
                allowedToOpen &= false;
                errorMessage +=
                    string.Format("{0} is already running.{1}", Constants.AssemblyTitle, Environment.NewLine);
#endif
            }
+4  A: 

EDIT: Improved the answer according to this cw question ...

You can use a mutex for checking wether the app already runs:

using( var mutex = new Mutex( false, AppGuid ) )
{
    try
    {
        try
        {
            if( !mutex.WaitOne( 0, false ) )
            {
                MessageBox.Show( "Another instance is already running." );
                return;
            }
        }
        catch( AbandonedMutexException )
        {
            // Log the fact the mutex was abandoned in another process,
            // it will still get aquired
        }

        Application.Run(new Form1());
    }
    finally
    {
        mutex.ReleaseMutex();
    }
}

Important is the AppGuid - you could make it depend on the user.

Maybe you like to read this article: the misunderstood mutex

tanascius
Works for me. Thanks!
Russ
+2  A: 

As tanascius already say, you can use the Mutex.

On a server that is running Terminal Services, a named system mutex can have two levels of visibility. If its name begins with the prefix "Global\", the mutex is visible in all terminal server sessions. If its name begins with the prefix "Local\", the mutex is visible only in the terminal server session where it was created.

Source: msdn, Mutex Class

A: 

If Form1 launches non-background threads, and that Form1 exits, you've got a problem: the mutex is released but the process is still there. Something along the lines below is better IMHO:

static class Program {
    private static Mutex mutex;



    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main() {
        bool createdNew = true;
        mutex = new Mutex(true, @"Global\Test", out createdNew);
        if (createdNew) {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());        
        }
        else {
            MessageBox.Show(
                "Application is already running",
                "Error",
                MessageBoxButtons.OK,
                MessageBoxIcon.Error
            );
        }
    }
}

The mutex won't be released as long as the primary application domain is still up. And that will be around as long as the application is running.

Christophe Keller