gpt4 book ai didi

c# - 尝试打开互斥量时出现 UnauthorizedAccessException

转载 作者:可可西里 更新时间:2023-11-01 12:40:46 26 4
gpt4 key购买 nike

我在尝试打开互斥量时遇到此异常(它只是有时发生;大多数调用都是成功的):

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,不可能有名称冲突。
这是唯一可以创建该互斥锁的代码,它授予所有用户对其的完全访问权限(我的进程可以在不同的用户凭据下运行)。

任何想法,为什么会发生这种未经授权的访问错误?

最佳答案

这个类应该可以解决你的问题:

    public class MutexLocker: IDisposable
{
private Mutex _mutex;

public MutexLocker ( string id )
{
bool createdNew;
MutexSecurity mutexSecurity = new MutexSecurity();
mutexSecurity.AddAccessRule(new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Allow));

try
{
// attempt to create the mutex, with the desired DACL..
_mutex = new Mutex(false, id, out createdNew, mutexSecurity);
}
catch (WaitHandleCannotBeOpenedException)
{
// the mutex cannot be opened, probably because a Win32 object of a different
// type with the same name already exists.
throw;
}
catch (UnauthorizedAccessException)
{
// the mutex exists, but the current process or thread token does not
// have permission to open the mutex with SYNCHRONIZE | MUTEX_MODIFY rights.
throw;
}
}

public void Dispose ()
{
if (_mutex != null)
{
_mutex.ReleaseMutex();
_mutex.Dispose();
}

_mutex = null;
}
}

唯一需要注意的是 Mutex 构造函数,它将尝试创建互斥锁(通过调用 Win32 的 CreateMutex())立即将提供的安全描述符分配给命名对象。如果 CreateMutex 调用失败,框架将尝试使用 OpenMutex 打开指定的互斥锁,请求 SYNCHRONIZEMUTEX_MODIFY 权限。

您看到的问题是互斥量的创建和安全描述符的分配之间的简单竞争条件(至少据我所知)。使创建和安全描述符分配原子化将解决该问题。

关于c# - 尝试打开互斥量时出现 UnauthorizedAccessException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19536697/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com