ExceptProc没有在Windows中调用

时间:2008-10-22 18:01:07

标签: delphi exception exception-handling

我目前正在尝试创建一个内置于我的Windows服务中的异常处理程序,在未处理的异常中,它会向另一个程序发送消息。我已经构建了方法并使通信工作,但似乎每次我的程序抛出错误,(我在代码中有一个加注调用来强制它。)windows捕获它而不调用Handler。谁能解释我做错了什么?。

简化代码解释:

procedure unhandled();
  begin
    raise Exception.Create('Unhandled');
  end;

procedure ExceptionHandler(ExceptObject: TObject; ExceptAddr: Pointer);
  begin
    WriteLn('Display: ' + Exception(ExceptObject).Message);
    //send Message Here
  end;

我调用此代码来运行它:

WriteLn('Starting');    

ExceptProc := @ExceptionHandler;    

unhandled();

我希望输出为:

  

启动
  显示:未处理

但它只是显示:

  

启动

然后Windows在大约5秒后返回命令提示符。

为什么处理程序没有被正确调用?

P.S。我一直在控制台应用程序中运行这些测试进行测试。

编辑:

以下是更多信息:

显然当你有一个指定的ExceptProc时,你的程序不应该抛出正常的运行时217错误。我猜这就是windows正在捕捉的东西,但是我可以看到,我的程序正在抛出运行时错误,我也无法得到ErrorProc来抓住它。

2 个答案:

答案 0 :(得分:8)

您错过了对SetErrorMode()的电话:

SetErrorMode(SEM_NOGPFAULTERRORBOX);

这是为了防止操作系统unhandled exception filter显示对话框/显示调试器附加对话框。这是一个完整的样本,在我的机器上按预期运行:

{$apptype console}

uses Windows, SysUtils;

procedure unhandled();
begin
  raise Exception.Create('Unhandled');
end;

procedure ExceptionHandler(ExceptObject: TObject; ExceptAddr: Pointer);
begin
  Writeln('here');
  WriteLn('Display: ' + Exception(ExceptObject).Message);
  Flush(Output);
  Halt(1);
end;

procedure Go;
begin
  unhandled;
end;

begin
  ExceptProc := @ExceptionHandler;
  SetErrorMode(SEM_NOGPFAULTERRORBOX);
  Go;
end.

请注意,SetErrorMode()的效果在正在运行的进程中的所有线程中都是全局的。

答案 1 :(得分:0)

有趣。

如果在Delphi IDE中运行应用程序(2007年试过),则会调用自定义异常处理程序,但如果从命令提示符运行它则不会。

另一个有趣的事情 - 我将主程序代码更改为

begin
  WriteLn('Starting');
  try
    ExceptProc := @ExceptionHandler;
    Unhandled;
  finally Readln; end;
end.

并注意到异常消息仅在我按下Enter键后显示(以获取Readln的一些输入)。因此,处理异常时会处理您的处理程序,但处理它时(在包含所有代码的隐式try..except中)。有意义。

必须是这个隐式try..except然后,但我在这台机器上缺少非Delphi调试器,无法进一步挖掘。也许别人知道答案......