使用模拟时互斥创建挂起

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 某些东西,但没有提到阻塞。

其他一些观察结果,可能相关也可能不相关:

可能底层系统资源发生了一些问题,但我们无法弄清楚。如何实现?

更新: 根据 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\",希望这是适合您的解决方法。