如何从其他程序中捕获异常(用于记录)?

时间:2010-03-20 10:43:47

标签: c# .net winapi exception

我正在研究一种监视大量应用程序的工具,并确保它们始终在运行并处于干净状态。其中一些应用程序具有未处理的异常,这些异常会定期发生并显示“发送崩溃报告”窗口。我没有这些应用程序的源代码。

我是否可以使用任何机制来捕获异常,或者只是识别它们的异常类型,以及识别引发异常的应用程序的主要可执行文件。

尝试代表应用程序执行像catch一样疯狂的事情并且处理它,我只是尝试捕获异常类型,记录它和然后重启应用程序。

3 个答案:

答案 0 :(得分:2)

捕获未处理的异常需要在进程中调用SetUnhandledExceptionFilter()。如果您没有源代码,那将很难做到,尽管injecting a DLL在技术上可以进入流程。但是,使用托管代码无法完成此操作,无法正确初始化CLR。

Windows安装的默认未处理异常处理程序将始终运行Windows错误报告工具WerFault.exe。这可以关闭,但这是一个系统设置。期望您的用户或管理员这样做是不现实的。只有在WER运行之后,JIT调试器才能获得它。

我推荐一种更简单的方法,一种更具选择性的方法。使用Process类可以获得您感兴趣的保护程序。触发Exited事件时,使用ExitCode属性查明它是如何终止的。任何负值都表明进程在未处理的异常中死亡,退出代码与异常代码匹配。您可以使用EventLog类来读取WER写入Windows事件日志的事件消息。你可以像启动它一样重启它。

答案 1 :(得分:1)

如果不修改应用程序的源代码或将DLL注入进程,我认为这不可能以可靠的方式进行。您要做的是检查跨过程边界的类型信息。由于多种原因,这并不容易实现

  • 获取异常的名称意味着在目标进程中执行代码。名称可以通过多种方式生成(.ToString,或.GetType()。Name),但都涉及执行某些方法
  • 您希望在应用程序崩溃后执行此操作,因此可能处于非常糟糕的状态。如果内存已损坏(甚至可能破坏该类型的内存定义),请考虑尝试执行代码。
  • 崩溃可能发生在本机代码中,不涉及任何托管数据

答案 2 :(得分:1)

如果要监视系统范围内的应用程序崩溃,可以将自己注册为即时调试程序。您可以编辑注册表以指定应用程序崩溃时要运行的调试器。他们提供的示例是Doctor Watson,但它可能是您的应用程序。