.NET COM 互操作 -> 全局异常处理程序

.NET COM Interop -> Global exception handler

我有一个 .NET 程序集,它是通过 COM Interop 从 Delphi 主机调用的。 我知道 .NET 代码中任何未处理的异常都将由 .net com 互操作框架处理,并且相应的 HRESULT 将返回到 COM 主机 (delphi)。但是,在此 HRESULT 异常转换期间,堆栈信息丢失。

问题是我们想在 .net 代码中记录所有未处理的异常,但我还没有找到任何方法来注册一个在此类异常发生时实际调用的包罗万象的处理程序。

我试过:

但在 COM Interop 下 运行 时不会调用这些。

是否可以为 COM 互操作框架定义某种 handler/callback 未处理的异常?或者以某种方式挂钩将托管异常转换为 HRESULT 的过程,以便可以记录异常?

谢谢!

我认为这里最好的选择是使用类似

的东西
void ComClassMethod()
{
    try { ... } 
    catch (Exception ex) 
    { 
        /* store the ex in the object */; 
        throw; 
    } 
}

C# 方法中的任何地方都暴露给 COM。

或者,您可以处理 AppDomain.CurrentDomain.FirstChanceException 并存储最后的 1st-chance 异常,您也可以将其公开给 COM。

但是,如果您的 COM 对象支持多线程,请特别注意(注意,大多数 .NET COM )。在这种情况下,您需要维护线程与其对应的最新异常之间的映射,无论是针对每个对象还是通过 System.Threading.ThreadLocal<T> 全局维护(确定更适合您的日志记录要求)。


已更新,我一直在想,必须有更好的方法来做到这一点。在 Adam Nathan 出色的“.NET 和 COM:完整的互操作性指南”一书中,确实有一个 explained here。我不确定我是否可以 copy/paste 完全引用受版权保护的 material,但我的想法如下:

  • 所有 .NET CCW 对象实现 ISupportErrorInfo
  • 扩展错误信息 - 通过 IErrorInfo object - can be retrieved on COM side via GetErrorInfo API.
  • 根据 Adam Nathan 的说法,此对象 也是 .NET 异常对象本身 ,它实现了 _Exception COM 接口。
  • COM 客户端可以使用 _Exception 获取所有详细信息,包括 _Exception.StackTrace

这似乎正是您要找的。