我想禁用 Delphi 捕获的异常并让 Windows 捕获它 - 使其产生一个像“AppName crashed.Debug, Send”这样的窗口,将其添加到应用程序事件中,创建内存转储等等。
默认情况下,Delphi 会捕获 TApplication.Run 过程中的所有异常...如何在不修改 Forms.pas 的情况下避免这种情况?
您可以添加一个OnException
重新引发异常的处理程序:
class procedure TMainForm.OnException(Sender: TObject; E: Exception);
begin
raise Exception(AcquireExceptionObject);
end;
initialization
Application.OnException := TMainForm.OnException;
不过,我不确定您为什么要这样做。使用 madExcept 或 EurekaLog 之类的工具来显示错误对话框更为正常,该对话框产生的信息比系统对话框有用得多。
您可以设置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。
添加您自己的处理程序。Application.OnException
可能是你想要的。也比把它留给 Windows 更好,因为您会根据环境获得不同的行为。例如,如果打开 Windows 错误报告,它会询问用户是否要向 MS 发送错误报告。
像 Heffernan 先生一样,我建议你看看 EurekaLog 之类的东西。
作为。我同意上面的声音,这个愿望很奇怪。我也同意实际上挂钩 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 只会让搜索变得更容易。