尝试打开互斥锁时出现此异常(仅有时会发生;大多数调用都是成功的):
System.UnauthorizedAccessException: Access to the path 'Global\4c7cddf7-e729-43b6-a75c-43f54a0ac6ac' is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.Threading.Mutex.OpenExisting(String name, MutexRights rights)
我用来处理互斥锁的代码:
public class MutexLocker : IDisposable
{
public MutexLocker(string id)
{
var doesNotExist = false;
var unauthorized = false;
try
{
_mutex = Mutex.OpenExisting(id, MutexRights.Synchronize | MutexRights.Modify);
}
catch (WaitHandleCannotBeOpenedException)
{
doesNotExist = true;
}
catch (UnauthorizedAccessException ex)
{
unauthorized = true;
}
if (doesNotExist)
{
_mutex = new Mutex(false, id);
var allowEveryoneRule = new MutexAccessRule(
new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow);
var securitySettings = new MutexSecurity();
securitySettings.AddAccessRule(allowEveryoneRule);
_mutex.SetAccessControl(securitySettings);
}
else if (unauthorized)
{
var tempMutex = Mutex.OpenExisting(id, MutexRights.ReadPermissions | MutexRights.ChangePermissions);
var securitySettings = tempMutex.GetAccessControl();
var user = Environment.UserDomainName + "\\" + Environment.UserName;
// the rule that denied the current user the right to enter and release the mutex must be removed
var rule = new MutexAccessRule(user, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Deny);
securitySettings.RemoveAccessRule(rule);
// Now grant the correct rights
var allowEveryoneRule = new MutexAccessRule(
new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow);
securitySettings.AddAccessRule(allowEveryoneRule);
tempMutex.SetAccessControl(securitySettings);
_mutex = Mutex.OpenExisting(id, MutexRights.Synchronize | MutexRights.Modify);
}
var success = _mutex.WaitOne(TimeSpan.FromSeconds(10), false);
if (success == false)
{
_mutex.Dispose();
_mutex = null;
throw new ApplicationException(string.Format("Can't lock mutex (timed out): {0}", id));
}
}
public void Dispose()
{
if (_mutex != null)
{
try
{
_mutex.ReleaseMutex();
}
catch (Exception exc)
{
Trace.WriteLine(exc);
}
_mutex.Dispose();
}
}
private readonly Mutex _mutex;
}
互斥体“id”是一个 guid,名称冲突是不可能的。
这是唯一可以创建该互斥体的代码,它授予所有用户对其的完全访问权限(我的进程可以在不同的用户凭据下运行)。
任何想法,为什么会发生这种未经授权的访问错误?