使用模拟时互斥创建挂起
Mutex creation hangs while using impersonation
在测试应用程序时,我 运行 陷入了 st运行ge 行为。一些测试使用模拟 运行 代码作为不同的用户,但它们总是会挂起,永远不会完成。
经过一些调查,问题缩小到互斥体的使用。本来我们是根据MSDN documentation, but even when using the SimpleImpersonation library使用自己的模拟代码,问题依旧。
这是重现问题的最小示例:
using (Impersonation.LogonUser(DOMAIN, USER, PASSWORD, LogonType.Interactive))
{
Console.WriteLine("Impersonated");
bool mine;
using (new Mutex(true, "Mutex", out mine))
{
if (!mine)
throw new Exception("Couldn't get mutex");
Console.WriteLine("Got mutex");
}
}
Console.WriteLine("Finished");
这永远不会完成,它停留在创建互斥量的线上。 documentation 指出它应该抛出异常或 return 某些东西,但没有提到阻塞。
其他一些观察结果,可能相关也可能不相关:
- 如果我们 "impersonate" 当前用户,它 return 立即
- 如果我们 运行 实际应用程序并启动另一个实例作为
不同的用户,一切正常
可能底层系统资源发生了一些问题,但我们无法弄清楚。如何实现?
更新: 根据 Hans 的评论,我尝试禁用 Windows Defender,但没有帮助。这是它挂起的地方的堆栈跟踪:
ntdll.dll!_NtWaitForSingleObject@12()
KernelBase.dll!_WaitForSingleObjectEx@12()
mscorlib.ni.dll!719c1867()
[Frames below may be incorrect and/or missing, native debugger attempting to walk managed call stack]
mscorlib.ni.dll!719c1852()
[Managed to Native Transition]
mscorlib.dll!System.Threading.Mutex.CreateMutexHandle(bool initiallyOwned, string name, Microsoft.Win32.Win32Native.SECURITY_ATTRIBUTES securityAttribute, out Microsoft.Win32.SafeHandles.SafeWaitHandle mutexHandle)
mscorlib.dll!System.Threading.Mutex.MutexTryCodeHelper.MutexTryCode(object userData)
[Native to Managed Transition]
[Managed to Native Transition]
mscorlib.dll!System.Threading.Mutex.CreateMutexWithGuaranteedCleanup(bool initiallyOwned, string name, out bool createdNew, Microsoft.Win32.Win32Native.SECURITY_ATTRIBUTES secAttrs)
mscorlib.dll!System.Threading.Mutex.Mutex(bool initiallyOwned, string name, out bool createdNew, System.Security.AccessControl.MutexSecurity mutexSecurity)
mscorlib.dll!System.Threading.Mutex.Mutex(bool initiallyOwned, string name, out bool createdNew)
MutexImpersonationTest.exe!MutexImpersonationTest.Program.Main(string[] args) Line 16
看起来获取 Mutex 的代码陷入了无限循环,在我的测试中,它在对 new Mutex(...)
.
的调用中将一个核心固定在 100%。
原因似乎是框架代码首先尝试调用 Win32 CreateMutex
,如果失败并出现 "Access Denied" 错误,则尝试调用 OpenMutex
。如果 OpenMutex
调用失败并显示互斥量不存在的错误,它会再次重复整个过程,因此如果互斥量不存在就会陷入无限循环。
根据 CreateMutex
documentation,这基本上是正确的方法,但似乎没有考虑初始 CreateMutex
失败并拒绝访问 的情况不是,因为对现有互斥锁的权限。
在我尝试时似乎确实有效的一件事是在互斥锁名称前加上 "Global\",希望这是适合您的解决方法。
在测试应用程序时,我 运行 陷入了 st运行ge 行为。一些测试使用模拟 运行 代码作为不同的用户,但它们总是会挂起,永远不会完成。
经过一些调查,问题缩小到互斥体的使用。本来我们是根据MSDN documentation, but even when using the SimpleImpersonation library使用自己的模拟代码,问题依旧。 这是重现问题的最小示例:
using (Impersonation.LogonUser(DOMAIN, USER, PASSWORD, LogonType.Interactive))
{
Console.WriteLine("Impersonated");
bool mine;
using (new Mutex(true, "Mutex", out mine))
{
if (!mine)
throw new Exception("Couldn't get mutex");
Console.WriteLine("Got mutex");
}
}
Console.WriteLine("Finished");
这永远不会完成,它停留在创建互斥量的线上。 documentation 指出它应该抛出异常或 return 某些东西,但没有提到阻塞。
其他一些观察结果,可能相关也可能不相关:
- 如果我们 "impersonate" 当前用户,它 return 立即
- 如果我们 运行 实际应用程序并启动另一个实例作为 不同的用户,一切正常
可能底层系统资源发生了一些问题,但我们无法弄清楚。如何实现?
更新: 根据 Hans 的评论,我尝试禁用 Windows Defender,但没有帮助。这是它挂起的地方的堆栈跟踪:
ntdll.dll!_NtWaitForSingleObject@12()
KernelBase.dll!_WaitForSingleObjectEx@12()
mscorlib.ni.dll!719c1867()
[Frames below may be incorrect and/or missing, native debugger attempting to walk managed call stack]
mscorlib.ni.dll!719c1852()
[Managed to Native Transition]
mscorlib.dll!System.Threading.Mutex.CreateMutexHandle(bool initiallyOwned, string name, Microsoft.Win32.Win32Native.SECURITY_ATTRIBUTES securityAttribute, out Microsoft.Win32.SafeHandles.SafeWaitHandle mutexHandle)
mscorlib.dll!System.Threading.Mutex.MutexTryCodeHelper.MutexTryCode(object userData)
[Native to Managed Transition]
[Managed to Native Transition]
mscorlib.dll!System.Threading.Mutex.CreateMutexWithGuaranteedCleanup(bool initiallyOwned, string name, out bool createdNew, Microsoft.Win32.Win32Native.SECURITY_ATTRIBUTES secAttrs)
mscorlib.dll!System.Threading.Mutex.Mutex(bool initiallyOwned, string name, out bool createdNew, System.Security.AccessControl.MutexSecurity mutexSecurity)
mscorlib.dll!System.Threading.Mutex.Mutex(bool initiallyOwned, string name, out bool createdNew)
MutexImpersonationTest.exe!MutexImpersonationTest.Program.Main(string[] args) Line 16
看起来获取 Mutex 的代码陷入了无限循环,在我的测试中,它在对 new Mutex(...)
.
原因似乎是框架代码首先尝试调用 Win32 CreateMutex
,如果失败并出现 "Access Denied" 错误,则尝试调用 OpenMutex
。如果 OpenMutex
调用失败并显示互斥量不存在的错误,它会再次重复整个过程,因此如果互斥量不存在就会陷入无限循环。
根据 CreateMutex
documentation,这基本上是正确的方法,但似乎没有考虑初始 CreateMutex
失败并拒绝访问 的情况不是,因为对现有互斥锁的权限。
在我尝试时似乎确实有效的一件事是在互斥锁名称前加上 "Global\",希望这是适合您的解决方法。