【发布时间】:2011-04-17 02:39:08
【问题描述】:
我在 C# 中创建了一个 Com 服务器。项目类型为类库。 有没有办法在我的代码中获取未处理异常的事件?我试过 AppDomain.CurrentDomain.UnhandledException 没有任何运气
【问题讨论】:
-
您一直处于托管代码中,还是需要处理非托管代码异常?无论哪种方式,您都应该能够在使用库中的内容时捕获异常。入口点是什么?
我在 C# 中创建了一个 Com 服务器。项目类型为类库。 有没有办法在我的代码中获取未处理异常的事件?我试过 AppDomain.CurrentDomain.UnhandledException 没有任何运气
【问题讨论】:
不可能。 CLR 中的 COM 互操作支持代码实现了 COM 中的限制,即不允许异常从 COM 方法中转义。您的方法将使用 CLR 内的捕获所有异常处理程序来调用,该处理程序捕获您抛出的任何异常。它被转换为 COM 错误代码、HRESULT、任何 COM 自动化兼容接口方法的返回值。 Exception.HResult 的值。 COM 客户端代码使用该值来确定方法调用是否失败。
您可以另外使用调试器并使其在任何异常时停止。 Debug + Exceptions,勾选 Throw 复选框。调试器会自动中断“第一次机会”异常。
【讨论】:
因为这是不可能的,如 Hans Passant 的回答中所述,并且由于在将异常转换为 COM HRESULT 时会丢失诸如堆栈跟踪之类的有用信息,所以我经常使用显式接口实现来确保在我的ComVisible 库是从 COM 客户端调用的。有点工作,但 COM 接口往往是稳定的,所以只做一次。
例如:
[ComVisible(true)]
public interface IMyClass
{
void MyMethod();
...
}
[
ComVisible(true),
ClassInterface(ClassInterfaceType.None)
]
public MyClass : IMyClass
{
...
public MyMethod()
{
... implementation
}
void IMyClass.MyMethod()
{
try
{
this.MyMethod();
}
catch(Exception ex)
{
_logger.Log(ex);
throw;
}
}
}
【讨论】: