代码之家  ›  专栏  ›  技术社区  ›  molnarm

使用模拟时Mutex创建挂起

  •  5
  • molnarm  · 技术社区  · 8 年前

    在测试应用程序时,我遇到了一个奇怪的行为。有些测试使用模拟以不同用户的身份运行代码,但它们总是挂起,永远不会完成。

    经过一些调查,问题被缩小到互斥体的使用。最初,我们基于 MSDN documentation ,但即使使用 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 声明它应该抛出一个异常或返回一些东西,但没有提到阻塞。

    其他一些可能或可能不相关的观察结果:

    • 如果我们“模拟”当前用户,它将立即返回
    • 如果我们运行实际应用程序并启动另一个实例作为 不同的用户,一切都按预期工作

    可能底层系统资源有问题,但我们无法解决。如何使其工作?

    更新: 根据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   
    
    1 回复  |  直到 7 年前
        1
  •  7
  •   Iridium    8 年前

    获取Mutex的代码似乎陷入了一个无限循环,在我的测试中,它将一个内核固定在对 new Mutex(...) .

    原因似乎是框架代码首先尝试调用Win32 CreateMutex ,如果失败并出现“拒绝访问”错误,则尝试调用 OpenMutex 相反如果 OpenMutex公司 调用失败,错误指示互斥体不存在,它再次重复整个过程,因此如果互斥体并不存在,就会陷入无限循环。

    根据 CreateMutex documentation ,这基本上是正确的方法,但似乎无法解释最初 创建Mutex 失败,访问被拒绝 由于对现有互斥体的权限。

    当我尝试使用它时,有一件事似乎确实有效,那就是在互斥体名称前面加上“Global\”,希望这是一个适合您的解决方法。