1

What is the correct way to set up the EventWaitHandleSecurity in the following sample that uses EventWaitHandle to ensure a single instance application?

    /// <summary>
    /// The method either:
    /// 1) acquires mutex and starts listing if anyone tries to get the same mutex,
    /// or
    /// 2) notifies the instance that actually owns the mutex
    /// </summary>
    /// <param name="isSystemWide">
    /// true if mutex is system wide (can belong to any user of the system),
    /// false if there could be one mutex per active user
    /// </param>
    /// <param name="instanceName">The name of the mutex</param>
    /// <param name="callback">Callback to be raised after the mutex is acquired
    /// on every time another instance tries (and fails) to acquire the mutex</param>
    /// <returns>
    /// true if mutex is acquired (and event is subsribed),
    /// false otherwise (and the mutex owner is notified)
    /// </returns>
    public static bool TryListenOrNotify(bool isSystemWide, string instanceName, Action callback)
    {
        var name = (isSystemWide ? "Global" : "Local") + "\\" + instanceName;

        var securityIdentifier = new SecurityIdentifier(WellKnownSidType.WorldSid, (SecurityIdentifier)null);
        var rule = new EventWaitHandleAccessRule(securityIdentifier, EventWaitHandleRights.FullControl, AccessControlType.Allow);
        var waitHandleSecurity = new EventWaitHandleSecurity();
        waitHandleSecurity.AddAccessRule(rule);

        bool createdNew;
        var eventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, name, out createdNew, waitHandleSecurity);
        if(createdNew)
        {
            // mutex not acquired
            var thread = new Thread(() =>
            {
                using(eventWaitHandle)
                {
                    // listening for notifications
                    while(eventWaitHandle.WaitOne())
                    {
                        callback();
                    }
                }
            });
            thread.IsBackground = true;
            thread.Start();
            return true;
        }
        else
        {
            // mutex is not acquired
            using(eventWaitHandle)
            {
                // notifying the mutex owner
                eventWaitHandle.Set();
            }
            return false;
        }
    }

In particular, I don't like to blindly grant all access to everyone. But I can't figure it out what is the default security settings and what is the least privilege set in that case?

Thank you.

  • Why don't you follow any of [these solutions](http://stackoverflow.com/questions/19147/what-is-the-correct-way-to-create-a-single-instance-application?rq=1). Simon_Weaver's and Dale Ragan's answer are good alternates. – Sriram Sakthivel May 12 '14 at 04:16
  • 1
    Those solutions do not offer proper way to notify the main application instance. Most of them ignore it at all, some of them do it improperly, others - use WCF (!) for this simple task. – Ilya Gerasimets May 12 '14 at 05:43
  • So `OnStartupNextInstance` overridden method doesn't satisfy you? – Sriram Sakthivel May 12 '14 at 05:45
  • Welcome, I'll mark this as duplicate question. I hope you don't mind. – Sriram Sakthivel May 13 '14 at 06:33
  • There are many discussions, and still my solution is different due to notifications handling: 1. It is thread safe (the same object is used for notifications rather than additional process enumerations). 2. It is not platform dependent (WinForms, WPF, Console, Service, etc.) 3. It is lightweight (no WCF services for notifications). 4. The first instance of applications handles notifications rather than the second sends the first to foreground. – Ilya Gerasimets May 14 '14 at 07:32

0 Answers0