0

Done like described:

What is the correct way to create a single-instance application?

or

http://www.c-sharpcorner.com/UploadFile/f9f215/how-to-restrict-the-application-to-just-one-instance/

The mutex works fine inside the user session. But it doesn't work, when I am switching users. May it be because one user is a domain user and the other user where I start the program is a local user? I haven't tested it yet with two local users...

I need to have only one instance on the computer.

I expect, the mutex to be OS wide. Is that a false assumption?

public partial class App : Application
{
    private static Mutex _InstanceMutex = null;

    private void Application_Startup(object sender, StartupEventArgs e)
    {
        bool isNewMutex;
        _InstanceMutex = new Mutex(true, "{ED75DE2B-69F7-4973-A58C-3A9D49B3E48D}", out isNewMutex);
        if (!isNewMutex)
        {
            _InstanceMutex = null;
            MessageBox.Show("Only one instance allowed", "ThisApp");
            Process.GetCurrentProcess().Kill();
            Application.Current.Shutdown();
            return;
        }
        //base.OnStartup(e);
    }

    private void Application_Exit(object sender, ExitEventArgs e)
    {
        if (_InstanceMutex != null)
            _InstanceMutex.ReleaseMutex();
        //base.OnExit(e);
    }
Community
  • 1
  • 1
MarkusEgle
  • 2,795
  • 4
  • 41
  • 61
  • As a side note, I would recommend that you bring the existing application to the foreground then show the messagebox (in front of it) or just bring the current app to the foreground and not even display a message (done by many many applications as a good user experience). – Erik Philips Aug 26 '15 at 15:30
  • 3
    Mutexes work across multiple threads and multiple processes. Never seen it said they work across sessions. –  Aug 26 '15 at 15:31
  • What's "not working" about it? Is it allowing an instance per user, multiple instances per user, or only one instance per machine? – Rowland Shaw Aug 26 '15 at 15:33
  • I need to have only one instance on the computer. – MarkusEgle Aug 26 '15 at 15:39
  • 3
    Have you tried giving the mutex a prefix "Global\" (per [the documentation for Terminal Servers](https://msdn.microsoft.com/en-us/library/bwe34f1k%28v=vs.110%29.aspx)) – Rowland Shaw Aug 26 '15 at 15:43
  • Global\ helps... now I'm getting UnauthorizedAccessException, and with try/catch I am able to react... perfect... – MarkusEgle Aug 26 '15 at 16:04

1 Answers1

1

I think you're going to want to pass MutexSecurity to the Mutex when you create it. The example at the bottom of the documentation shows how to lock a mutex down to a specific user. Also read in Remarks, that there is such thing as Global and Local sessions, which may or may not apply to you.

Mutex Constructor (Boolean, String, Boolean, MutexSecurity) to be used.

Edit

You could also try this approach:

if(!(Mutex.TryOpenExisting("Global\\{ED75DE2B-69F7-4973-A58C-3A9D49B3E48D}", out tempMutex)))
{
   _InstanceMutex = new Mutex(true, "Global\\{ED75DE2B-69F7-4973-A58C-3A9D49B3E48D}");
   //Continue startup normally
}
else
{
   //Already exists, shutdown app
}

This shouldn't throw an exception unless you set the mutex security.

Kcvin
  • 5,073
  • 2
  • 32
  • 54
  • Logon could be done from anybody from the domain. As far as I understood the MutexSecurity I need to add a mutexAccessRule per user who tries to gather details of the mutex. For me it seems to be the easiest way that the mutex name needs to start with "\Global" and then I just need to react to the UnauthorizedAccessException. – MarkusEgle Aug 26 '15 at 16:12
  • @MarkusEgle edited with possibly a non-throwing solution – Kcvin Aug 26 '15 at 17:06