6

我想禁用 Delphi 捕获的异常并让 Windows 捕获它 - 使其产生一个像“AppName crashed.Debug, Send”这样的窗口,将其添加到应用程序事件中,创建内存转储等等。

默认情况下,Delphi 会捕获 TApplication.Run 过程中的所有异常...如何在不修改 Forms.pas 的情况下避免这种情况?

4

4 回答 4

8

您可以添加一个OnException重新引发异常的处理程序:

class procedure TMainForm.OnException(Sender: TObject; E: Exception);
begin
  raise Exception(AcquireExceptionObject);
end;

initialization
  Application.OnException := TMainForm.OnException;

不过,我不确定您为什么要这样做。使用 madExcept 或 EurekaLog 之类的工具来显示错误对话框更为正常,该对话框产生的信息比系统对话框有用得多。

于 2012-08-26T18:08:54.957 回答
4

您可以设置JITEnable为“1”或更高(默认为“0”)。使用“1”,非本地异常,高于“1”,所有异常都将由 JIT 或 WER 处理(取决于系统)。

不过,这可能不是您想要的。使用此解决方案,任何合格的异常都将传递给操作系统,无论它们是否在代码中处理都没有关系。澄清(在调试器之外运行):

procedure TForm1.Button1Click(Sender: TObject);
begin
  raise EAccessViolation.Create('access denied');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  try
    PInteger(0)^ := 0;
  except
  end;
end;

initialization
  JITEnable := 1;

第一个例子是原生异常,为1时会被应用程序异常处理机制处理JITEnable。但第二个例子会触发JIT/WER。

于 2012-08-26T22:53:47.587 回答
3

添加您自己的处理程序。Application.OnException可能是你想要的。也比把它留给 Windows 更好,因为您会根据环境获得不同的行为。例如,如果打开 Windows 错误报告,它会询问用户是否要向 MS 发送错误报告。

像 Heffernan 先生一样,我建议你看看 EurekaLog 之类的东西。

于 2012-08-26T18:23:24.450 回答
1

作为。我同意上面的声音,这个愿望很奇怪。我也同意实际上挂钩 TApplication.OnException 可能就足够了(“如果它看起来像鸭子......”)

但是,如果您真的想让 RTL 忽略异常,也有一些方法。

异常处理程序是低级 RTL 的插件,就像堆管理等一样。

您可以查看 KOL(关键对象库)。在 Delphi 5 次中,我设法制作了 2KB 大小的 DLL。

这需要缺少许多被视为“理所当然”的功能。其中有例外。

要在 KOL 的系统 RTL 替换中启用异常,您必须制作一些 $DEFINE,然后解锁向 IDE 添加异常支持的代码。

我相信您仍然可以获得该模块化 RTL 版本并为该 $IfDef grep 并查看哪个代码被哪个代码替换。我相信您很有可能可以撤消该操作并让 Windows 避免通过异常调用 Delphi RTL。我不记得细节,但我相信 Delphi RTL 异常处理程序只是在 Windows 核心中注册为回调。而且您可能可以取消注册它(注册 nil 回调)。我相信你可以在股票 RTL 中找到它,但 KOL 的模块化 RTL 只会让搜索变得更容易。

于 2012-08-27T07:54:36.403 回答