public static void RunMeInSingleProcessOnly(Action <string> exitingMessage)
        {
            string        appName = ProgramRoutines.GetAppName();
            bool          createdNew;
            MutexSecurity mutexSecurity = new MutexSecurity();

            mutexSecurity.AddAccessRule(new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Allow));
            for (int i = 0; i < 2; i++)
            {
                try
                {
                    GLOBAL_SINGLE_PROCESS_MUTEX = new Mutex(false, @"Global\CLIVERSOFT_" + appName + @"_SINGLE_PROCESS", out createdNew, mutexSecurity);
                    break;
                }
                catch (Exception e)
                {//An “access denied” while creating a new Mutex can happen in the following situation:
                 //a.Process A running as an administrator creates a named mutex.
                 //b.Process B running as a normal user attempts to access the mutex which fails with “access denied” since only Administrators can access the mutex.
                    if (i == 0)
                    {
                        Thread.Sleep(1000);//wait for some time while contending, if the other instance of the program is still in progress of shutting down.
                        continue;
                    }
                    exitingMessage?.Invoke(Log.GetExceptionMessage(e) + "\r\n\r\nExiting...");
                    Environment.Exit(0);
                }
            }
            if (GLOBAL_SINGLE_PROCESS_MUTEX.WaitOne(1000, false))//wait for some time while contending, if the other instance of the program is still in progress of shutting down.
            {
                return;
            }
            exitingMessage?.Invoke(appName + " is already running, so this instance will exit.");
            Environment.Exit(0);
        }
 public static InfoWindow Create(string text, string image_url, string action_name, Action action, string sound_file = null, Brush box_brush = null, Brush button_brush = null)
 {
     return(Create(ProgramRoutines.GetAppName(), text, image_url, action_name, action, sound_file, box_brush, button_brush));
 }