为什么模拟代码的异常没有被捕获?

sha*_*oth 5 .net c# impersonation exception-handling exception

我的C#代码通过P/Invoke调用Win32函数来使用模拟

internal class Win32Native
{
    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern int ImpersonateLoggedOnUser(IntPtr token);

    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern int RevertToSelf();
}

try {
    var token = obtainTokenFromLogonUser();
    Win32Native.ImpersonateLoggedOnUser( token );
    throw new Exception(); // this is for simulation
    Win32Native.RevertToSelf()
} catch( Exception e ) {
    LogException( e );
    throw;
}
Run Code Online (Sandbox Code Playgroud)

我也AppDomain.CurrentDomain.UnhandledException安装了处理程序,也记录了所有未处理的异常.

我确信记录异常的代码在模拟和不模拟时都能正常工作.

现在的问题是,在上面的代码中看起来好像catch没有输入,UnhandledException也没有被调用.唯一的异常跟踪是事件查看器中的条目.

如果我添加finally这样的:

try {
    var token = obtainTokenFromLogonUser();
    Win32Native.ImpersonateLoggedOnUser( token );
    try {
       throw new Exception(); // this is for simulation
    } finally {
        Win32Native.RevertToSelf()
    }
} catch( Exception e ) {
    LogException( e );
    throw;
}
Run Code Online (Sandbox Code Playgroud)

那么catchUnhandledException处理程序和从处理程序都可以记录异常.

发生了什么?被模拟的线程是否会阻止通常的异常处理?

bob*_*der 3

如果没有看到 LogException 的代码,我无法确定,但可能是您在那里所做的任何事情都是在模拟/登录用户的上下文中执行的,并且该用户没有执行该操作的用户权限无论您正在做什么,例如写入文件等,代码都会在此时崩溃。事实上,你的代码只有在你“恢复到自我”之后才起作用,这一事实似乎证明了这一点。

所以我想说的是,你的异常很可能实际上是被 catch 捕获的,但是 LogException 由于它试图在不正确的用户上下文中工作而失败。

要对此进行测试,请在 LogException 内部尝试将当前上下文强制为“Self”,然后再尝试进行任何日志记录,并查看第一个片段现在是否开始工作。