public static void RunMeInSingleProcessOnly(Action <string> exitingMessage) { string appName = ProgramRoutines.GetAppName(); //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 _ /*, 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); }
/// <summary> /// /// </summary> /// <param name="as_administarator"></param> /// <param name="arguments">if NULL then reuse parameters of the calling process</param> public static void Restart(bool as_administarator = false, string arguments = "") { if (arguments == null) { arguments = Regex.Replace(Environment.CommandLine, @"^\s*(\'.*?\'|\"".*?\"")\s+", "", RegexOptions.Singleline); } ProcessStartInfo psi = new ProcessStartInfo(); psi.UseShellExecute = true; psi.WorkingDirectory = Environment.CurrentDirectory; psi.FileName = ProgramRoutines.GetAppPath(); if (as_administarator) { psi.Verb = "runas"; } psi.Arguments = arguments; if (GLOBAL_SINGLE_PROCESS_MUTEX != null) { GLOBAL_SINGLE_PROCESS_MUTEX.ReleaseMutex(); } try { Process.Start(psi); } catch { //if the user cancelled } Environment.Exit(0); }