static void Main() { // get application GUID as defined in AssemblyInfo.cs string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly(). GetCustomAttributes(typeof(GuidAttribute), false). GetValue(0)).Value.ToString(); // unique id for global mutex - Global prefix means it is global to the machine string mutexId = string.Format("Global\\{{{0}}}", appGuid); // Need a place to store a return value in Mutex() constructor call bool createdNew; var allowEveryoneRule = new MutexAccessRule( new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow); var securitySettings = new MutexSecurity(); securitySettings.AddAccessRule(allowEveryoneRule); using (var mutex = new Mutex(false, mutexId, out createdNew, securitySettings)) { var hasHandle = false; try { try { hasHandle = mutex.WaitOne(5000, false); if (hasHandle == false) { throw new System.TimeoutException("Timeout waiting for exclusive access"); } } catch (AbandonedMutexException) { // Log the fact that the mutex was abandoned in another process, // it will still get acquired hasHandle = true; } // Perform your work here. SQLServerMethods sqlServerMethods = new SQLServerMethods(); sqlServerMethods.StartApp(); } catch (System.TimeoutException) { // Log the fact that the mutex was abandoned in another process, // it will still get acquired MessageBox.Show("This application is limited to one user at a time. Try again later."); } finally { if (hasHandle) mutex.ReleaseMutex(); } } }