ミューテックスを開こうとすると、この例外が発生します (たまにしか発生しません。ほとんどの呼び出しは成功します)。
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 であり、名前の競合はあり得ません。
これは、そのミューテックスを作成できる唯一のコードであり、すべてのユーザーに完全なアクセスを許可します (私のプロセスは異なるユーザー資格情報で実行できます)。
この不正アクセスエラーが発生する理由は何ですか?