public static void Main() { // Create a string representing the current user. string user = Environment.UserDomainName + "\\" + Environment.UserName; // Create a security object that grants no access. MutexSecurity mSec = new MutexSecurity(); // Add a rule that grants the current user the // right to enter or release the mutex and read the // permissions on the mutex. MutexAccessRule rule = new MutexAccessRule(user, MutexRights.Synchronize | MutexRights.Modify | MutexRights.ReadPermissions, AccessControlType.Allow); mSec.AddAccessRule(rule); // Add a rule that denies the current user the // right to change permissions on the mutex. rule = new MutexAccessRule(user, MutexRights.ChangePermissions, AccessControlType.Deny); mSec.AddAccessRule(rule); // Display the rules in the security object. ShowSecurity(mSec); // Create a rule that grants the current user // the right to read permissions on the mutex, and // take ownership of the mutex. Use this rule to // remove the right to read permissions from the // Allow rule for the current user. The inclusion // of the right to take ownership has no effect. rule = new MutexAccessRule(user, MutexRights.TakeOwnership | MutexRights.ReadPermissions, AccessControlType.Allow); mSec.RemoveAccessRule(rule); ShowSecurity(mSec); }
internal static void Main() { //<Snippet2> const string mutexName = "MutexExample4"; Mutex m = null; bool doesNotExist = false; bool unauthorized = false; // The value of this variable is set by the mutex // constructor. It is true if the named system mutex was // created, and false if the named mutex already existed. // bool mutexWasCreated = false; // Attempt to open the named mutex. try { // Open the mutex with (MutexRights.Synchronize | // MutexRights.Modify), to enter and release the // named mutex. // m = Mutex.OpenExisting(mutexName); } catch (WaitHandleCannotBeOpenedException) { Console.WriteLine("Mutex does not exist."); doesNotExist = true; } catch (UnauthorizedAccessException ex) { Console.WriteLine("Unauthorized access: {0}", ex.Message); unauthorized = true; } //</Snippet2> // There are three cases: (1) The mutex does not exist. // (2) The mutex exists, but the current user doesn't // have access. (3) The mutex exists and the user has // access. // if (doesNotExist) { //<Snippet4> // The mutex does not exist, so create it. // Create an access control list (ACL) that denies the // current user the right to enter or release the // mutex, but allows the right to read and change // security information for the mutex. // string user = Environment.UserDomainName + "\\" + Environment.UserName; MutexSecurity mSec = new MutexSecurity(); MutexAccessRule rule = new MutexAccessRule(user, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Deny); mSec.AddAccessRule(rule); rule = new MutexAccessRule(user, MutexRights.ReadPermissions | MutexRights.ChangePermissions, AccessControlType.Allow); mSec.AddAccessRule(rule); // Create a Mutex object that represents the system // mutex named by the constant 'mutexName', with // initial ownership for this thread, and with the // specified security access. The Boolean value that // indicates creation of the underlying system object // is placed in mutexWasCreated. // m = new Mutex(true, mutexName, out mutexWasCreated, mSec); // If the named system mutex was created, it can be // used by the current instance of this program, even // though the current user is denied access. The current // program owns the mutex. Otherwise, exit the program. // if (mutexWasCreated) { Console.WriteLine("Created the mutex."); } else { Console.WriteLine("Unable to create the mutex."); return; } //</Snippet4> } else if (unauthorized) { //<Snippet3> // Open the mutex to read and change the access control // security. The access control security defined above // allows the current user to do this. // try { m = Mutex.OpenExisting(mutexName, MutexRights.ReadPermissions | MutexRights.ChangePermissions); // Get the current ACL. This requires // MutexRights.ReadPermissions. MutexSecurity mSec = m.GetAccessControl(); string user = Environment.UserDomainName + "\\" + Environment.UserName; // First, the rule that denied the current user // the right to enter and release the mutex must // be removed. MutexAccessRule rule = new MutexAccessRule(user, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Deny); mSec.RemoveAccessRule(rule); // Now grant the user the correct rights. // rule = new MutexAccessRule(user, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Allow); mSec.AddAccessRule(rule); // Update the ACL. This requires // MutexRights.ChangePermissions. m.SetAccessControl(mSec); Console.WriteLine("Updated mutex security."); // Open the mutex with (MutexRights.Synchronize // | MutexRights.Modify), the rights required to // enter and release the mutex. // m = Mutex.OpenExisting(mutexName); //</Snippet3> } catch (UnauthorizedAccessException ex) { Console.WriteLine("Unable to change permissions: {0}", ex.Message); return; } } // If this program created the mutex, it already owns // the mutex. // if (!mutexWasCreated) { // Enter the mutex, and hold it until the program // exits. // try { Console.WriteLine("Wait for the mutex."); m.WaitOne(); Console.WriteLine("Entered the mutex."); } catch (UnauthorizedAccessException ex) { Console.WriteLine("Unauthorized access: {0}", ex.Message); } } Console.WriteLine("Press the Enter key to exit."); Console.ReadLine(); m.ReleaseMutex(); m.Dispose(); }
/// <summary> /// /// </summary> /// <param name="mutexName">互斥对象的名称</param> /// <param name="tryCleanAbandoned">是否尝试释放已经存在的被放弃的mutex</param> /// <param name="mutex">成功时返回的互斥对象</param> /// <param name="errcode">错误代码,0无错误,1无法创建互斥对象,2互斥对象存在,无法获取访问权限,3互斥对象正被其他线程占用,4有被弃用的互斥对象,被本方法释放,5互斥对象已存在</param> /// <returns></returns> private static bool TryEnter(string mutexName, bool tryCleanAbandoned, out Mutex mutex, out int errcode) { mutex = null; errcode = 0; // 无错误 if (string.IsNullOrEmpty(mutexName)) { return(false); } Mutex m = null; bool doesNotExist = false; bool unauthorized = false; bool mutexWasCreated = false; bool hasAccessException = false; try { // 尝试打开现有的 m = Mutex.OpenExisting(mutexName); } catch (WaitHandleCannotBeOpenedException) { // 不存在 doesNotExist = true; } catch (UnauthorizedAccessException) { // 没有访问权限 unauthorized = true; } // 如果不存在则创建 if (doesNotExist) { MutexSecurity mSec = null; try { string user = Environment.UserDomainName + "\\" + Environment.UserName; mSec = new MutexSecurity(); MutexAccessRule rule = new MutexAccessRule(user, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Deny); mSec.AddAccessRule(rule); rule = new MutexAccessRule(user, MutexRights.ReadPermissions | MutexRights.ChangePermissions, AccessControlType.Allow); mSec.AddAccessRule(rule); } catch { hasAccessException = true; } if (hasAccessException) { m = new Mutex(true, mutexName, out mutexWasCreated); } else { m = new Mutex(true, mutexName, out mutexWasCreated, mSec); } if (mutexWasCreated) { mutex = m; return(true); } else { errcode = 1; //无法创建对象 return(false); } } // 尝试增加访问权限 if (unauthorized) { try { m = Mutex.OpenExisting(mutexName, MutexRights.ReadPermissions | MutexRights.ChangePermissions); MutexSecurity mSec = m.GetAccessControl(); string user = Environment.UserDomainName + "\\" + Environment.UserName; MutexAccessRule rule = new MutexAccessRule(user, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Deny); mSec.RemoveAccessRule(rule); rule = new MutexAccessRule(user, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Allow); mSec.AddAccessRule(rule); m.SetAccessControl(mSec); m = Mutex.OpenExisting(mutexName); } catch (UnauthorizedAccessException) { errcode = 2;// 无法获取访问权限 return(false); } catch (Exception) { errcode = 3;// mutex对象正被其他线程占用 return(false); } } // 对于已经存在的具备访问权限了 if (tryCleanAbandoned) { try { // 尝试立刻获取控制 bool waitSuccess = m.WaitOne(0); // 不排除有能正好获取到访问权限的 if (!waitSuccess) { errcode = 3;// mutex对象正被其他线程占用 } else { mutex = m; } return(waitSuccess); } // 如果发现是被弃用的 catch (AbandonedMutexException) { m.ReleaseMutex(); errcode = 4; // 有被弃用的mutex对象 return(false); } } else { errcode = 5; // mutex对象存在,用户未尝试释放 return(false); } }
/// <summary> /// Creates the Mutex /// </summary> public void CreateMutex() { bool doesNotExist = false; bool unauthorized = false; bool mutexWasCreated = false; // Attempt to open the named mutex. try { // Open the mutex with (MutexRights.Synchronize | // MutexRights.Modify), to enter and release the // named mutex. // Mutex m = Mutex.OpenExisting(Name); } catch (WaitHandleCannotBeOpenedException) { doesNotExist = true; } catch (UnauthorizedAccessException) { unauthorized = true; } // There are three cases: (1) The mutex does not exist. // (2) The mutex exists, but the current user doesn't // have access. (3) The mutex exists and the user has // access. // if (doesNotExist) { // The mutex does not exist, so create it. // Create an access control list (ACL) that denies the // current user the right to enter or release the // mutex, but allows the right to read and change // security information for the mutex. // string user = Environment.UserDomainName + "\\" + Environment.UserName; MutexSecurity mSec = new MutexSecurity(); MutexAccessRule rule = new MutexAccessRule(user, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Deny); mSec.AddAccessRule(rule); rule = new MutexAccessRule(user, MutexRights.ReadPermissions | MutexRights.ChangePermissions, AccessControlType.Allow); mSec.AddAccessRule(rule); // Create a Mutex object that represents the system // mutex named by the constant 'mutexName', with // initial ownership for this thread, and with the // specified security access. The Boolean value that // indicates creation of the underlying system object // is placed in mutexWasCreated. // _mutex = new Mutex(_initialOwner, Name, out mutexWasCreated, mSec); // If the named system mutex was created, it can be // used by the current instance of this program, even // though the current user is denied access. The current // program owns the mutex. Otherwise, exit the program. // if (!mutexWasCreated) { #if TRACE Console.WriteLine("Unable to create the mutex."); #endif return; } } else if (unauthorized) { // Open the mutex to read and change the access control // security. The access control security defined above // allows the current user to do this. // try { _mutex = Mutex.OpenExisting(Name, MutexRights.ReadPermissions | MutexRights.ChangePermissions); // Get the current ACL. This requires // MutexRights.ReadPermissions. MutexSecurity mSec = _mutex.GetAccessControl(); string user = Environment.UserDomainName + "\\" + Environment.UserName; // First, the rule that denied the current user // the right to enter and release the mutex must // be removed. MutexAccessRule rule = new MutexAccessRule(user, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Deny); mSec.RemoveAccessRule(rule); // Now grant the user the correct rights. // rule = new MutexAccessRule(user, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Allow); mSec.AddAccessRule(rule); // Update the ACL. This requires // MutexRights.ChangePermissions. _mutex.SetAccessControl(mSec); Console.WriteLine("Updated mutex security."); // Open the mutex with (MutexRights.Synchronize // | MutexRights.Modify), the rights required to // enter and release the mutex. // _mutex = Mutex.OpenExisting(Name); } #if TRACE catch (UnauthorizedAccessException ex) { Console.WriteLine("Unable to change permissions: {0}", ex.Message); } #else catch #endif { return; } } MutexCreated = mutexWasCreated; if (!mutexWasCreated) { _mutex.WaitOne(); } }
/// <summary> /// Gewährt Zugriff auf einen benannten System Mutex. /// </summary> /// <param name="mutexName"> /// Der Namen des benannten System Mutex. /// </param> /// <param name="create"> /// Gibt an ob der Mutex erzeugt werden soll wenn er noch nicht existiert. /// </param> /// <param name="allowAttach"> /// Gibt an ob der Mutex neu erzeugt werden muss oder existieren darf. /// </param> /// <returns> /// Einen benannten System Mutex oder <c>null</c> wenn der Mutex nicht exisitiert /// oder ein anderes Problem aufgetreten ist. /// </returns> /// <remarks> /// Versucht unter allen möglichen Umständen den zugfriff auf den Mutex zu /// erlangen oder ihn zu erzeugen. /// <para> /// 1) Der Mutex exisitiert nicht. /// </para> /// Es wird eine ACL erzeugt die dem Benutzer alle Rechte auf den Mutex einräumt /// und dem erzeugten Mutex zugewiesen /// <para> /// 2) Der Mutex exisitiert, doch der aktuelle Benutzer hat keinen Zugriff /// </para> /// Es wird die aktuelle Regel, die dem Benutzer den Zugriff auf den Mutex verweigert, /// entfernt. Dann wird versucht dem Benutzer die nötigen Rechte einzuräumen und /// die aktuaiserte Regel dem Mutex hinzugefügt. Wird diese Massname verweigert /// wird eine Ausnahme wegen unauthorisiertem Zugriff ausgelöst. /// <para> /// 3) Der Mutex existiert und der Benutzer hat Zugriff. /// </para> /// Hier sind keine Massnamen nötig. Der Mutex wird geöffnet und zurückgegeben. /// </remarks> private static Mutex getNamedMutex(string mutexName, bool create, bool allowAttach) { Mutex mutex = null; bool doesNotExist = false; bool unauthorized = false; /* Der Wert dieser Variable wird vom Mutex Konstruktor * gesetzt. Ist sie true wurde der benannte SystemMutex * erzeugt. Wenn der Wert false ist, exisitiert der Mutex * bereits. */ bool mutexWasCreated = false; // versuche den Mutex zu öffnen try { mutex = Mutex.OpenExisting(mutexName); if (!allowAttach && mutex != null) { // Erfolg, aber Mutex sollte neu sein mutex.Close(); throw new SharedMemoryException(); } } catch (WaitHandleCannotBeOpenedException) { // Mutex exisitiert nicht doesNotExist = true; } catch (UnauthorizedAccessException) { // keine Authorisierung unauthorized = true; } /* Es gibt 3 mögliche Lösungen: * (1) Der Mutex exisitiert nicht. * (2) Der Mutex exisitiert, doch der aktuelle Benutzer hat keinen Zugriff. * (3) Der Mutex existiert und der Benutzer hat Zugriff. */ #region (1) does Not Exist if (doesNotExist & create) { // Der Mutex existiert nicht und soll erzeugt werden, also erzeugen // Als erstes eine Access Control List (ACL) erzeugen, die dem // Benutzer alle Rechte auf den Mutex einräumt. string user = Environment.UserDomainName + "\\" + Environment.UserName; // eine Instanz von MutexSecurity erzeugen MutexSecurity mutexSec = new MutexSecurity(); // eine Instanz von MutexAccessRule mit voller Kontrolle erzeugen MutexAccessRule rule = new MutexAccessRule(user, MutexRights.FullControl, AccessControlType.Allow); // die ZugriffsRegel zuweisen mutexSec.AddAccessRule(rule); // den benannten Mutex mit dem Namen und der ZugriffsRegel erzeugen. mutex = new Mutex(false, mutexName, out mutexWasCreated, mutexSec); if (mutexWasCreated) { return(mutex); } else { throw new SharedMemoryException(); } } #endregion #region (2) unauthorized else if (unauthorized) { // Den Mutex öffnen um die ZugriffsSicherheit zu lesen // und zu ändern try { mutex = Mutex.OpenExisting(mutexName, MutexRights.ReadPermissions | MutexRights.ChangePermissions); // die aktuelle ACL holen. Das erfordert das Recht // MutexRights.ReadPermissions. MutexSecurity mutexSec = mutex.GetAccessControl(); // den aktuellen Benutzer einlesen string user = Environment.UserDomainName + "\\" + Environment.UserName; // Als erstes muss die Regel, die dem aktuellen Benutzer // das Sperren und Freigen des Mutex verbietet, entfernt werden. MutexAccessRule rule = new MutexAccessRule(user, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Deny); mutexSec.RemoveAccessRule(rule); // jetzt dem Benutzer die richtigen Rechte zuweisen rule = new MutexAccessRule(user, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Allow); mutexSec.AddAccessRule(rule); // aktualisieren der ACL. Das erfordert das Recht // MutexRights.ChangePermissions. mutex.SetAccessControl(mutexSec); // den Mutex öffnen mutex = Mutex.OpenExisting(mutexName); // und den Mutex zurückgeben return(mutex); } catch (UnauthorizedAccessException) { // neu auslösen der Ausname. throw; } } #endregion #region (3) Exist and Access granted if (!mutexWasCreated) { // Mutex existiert und der Benutzer hat Zugriff if (mutex != null) { return(mutex); } } #endregion return(null); }
/// <summary> /// Reperimento o creazione del Mutext per l'istanza corrente /// </summary> /// <param name="instance"></param> /// <returns></returns> private static Mutex GetOrCreateMutex(ChannelRefInfo instance) { string mutexName = string.Format("PublisherM-{0}-{1}", instance.Admin.Id.ToString(), instance.Id.ToString()); logger.DebugFormat("GetOrCreateMutex Name {0}", mutexName); Mutex m = null; bool doesNotExist = false; bool unauthorized = false; // The value of this variable is set by the mutex // constructor. It is true if the named system mutex was // created, and false if the named mutex already existed. // bool mutexWasCreated = false; // Attempt to open the named mutex. try { // Open the mutex with (MutexRights.Synchronize | // MutexRights.Modify), to enter and release the // named mutex. // m = Mutex.OpenExisting(mutexName); } catch (WaitHandleCannotBeOpenedException) { logger.DebugFormat("Mutex does not exist."); doesNotExist = true; } catch (UnauthorizedAccessException ex) { logger.DebugFormat("Unauthorized access: {0}", ex.Message); unauthorized = true; } // There are three cases: (1) The mutex does not exist. // (2) The mutex exists, but the current user doesn't // have access. (3) The mutex exists and the user has // access. // if (doesNotExist) { // The mutex does not exist, so create it. // Create an access control list (ACL) that denies the // current user the right to enter or release the // mutex, but allows the right to read and change // security information for the mutex. // string user = Environment.UserDomainName + "\\" + Environment.UserName; MutexSecurity mSec = new MutexSecurity(); MutexAccessRule rule = new MutexAccessRule(user, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Deny); mSec.AddAccessRule(rule); rule = new MutexAccessRule(user, MutexRights.ReadPermissions | MutexRights.ChangePermissions, AccessControlType.Allow); mSec.AddAccessRule(rule); // Create a Mutex object that represents the system // mutex named by the constant 'mutexName', with // initial ownership for this thread, and with the // specified security access. The Boolean value that // indicates creation of the underlying system object // is placed in mutexWasCreated. // m = new Mutex(true, mutexName, out mutexWasCreated, mSec); // If the named system mutex was created, it can be // used by the current instance of this program, even // though the current user is denied access. The current // program owns the mutex. Otherwise, exit the program. // if (mutexWasCreated) { logger.DebugFormat("Created the mutex."); } else { logger.DebugFormat("Unable to create the mutex."); throw new ApplicationException("Unable to create the mutex."); } } else if (unauthorized) { // Open the mutex to read and change the access control // security. The access control security defined above // allows the current user to do this. // try { m = Mutex.OpenExisting(mutexName, MutexRights.ReadPermissions | MutexRights.ChangePermissions); // Get the current ACL. This requires // MutexRights.ReadPermissions. MutexSecurity mSec = m.GetAccessControl(); string user = Environment.UserDomainName + "\\" + Environment.UserName; // First, the rule that denied the current user // the right to enter and release the mutex must // be removed. MutexAccessRule rule = new MutexAccessRule(user, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Deny); mSec.RemoveAccessRule(rule); // Now grant the user the correct rights. // rule = new MutexAccessRule(user, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Allow); mSec.AddAccessRule(rule); // Update the ACL. This requires // MutexRights.ChangePermissions. m.SetAccessControl(mSec); logger.DebugFormat("Updated mutex security."); // Open the mutex with (MutexRights.Synchronize // | MutexRights.Modify), the rights required to // enter and release the mutex. // m = Mutex.OpenExisting(mutexName); } catch (UnauthorizedAccessException ex) { logger.DebugFormat("Unable to change permissions: {0}", ex.Message); throw new ApplicationException(string.Format("Unable to change permissions: {0}", ex.Message)); } } return(m); }