2008-10-22 18 views
4

我目前正在嘗試創建一個內置到我的Windows服務中的異常處理程序,該程序在未處理的異常情況下向另一個程序發送消息。我已經構建了方法並獲得了通信工作,但似乎每當我的程序拋出錯誤(我在代碼中強制調用它時),windows都會捕獲它,而Handler不會被調用。任何人都可以解釋我做錯了什麼?ExceptProc未在Windows中調用

簡化的代碼解釋:

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(); 

我希望可以將輸出爲:

開始
顯示:未處理

但它是所有顯示:

開始

然後窗口返回約5秒鐘後的命令提示。

爲什麼不正確調用處理程序?

P.S.我一直在控制檯應用程序中運行這些測試以進行測試。

編輯:

這裏有一些更多的信息:

顯然,當你有一個分配ExceptProc,你的程序不應該拋出正常運行時217錯誤。我猜這是Windows捕獲的東西,但是從我所看到的,但是我的程序正在拋出運行時錯誤,並且我也無法獲得ErrorProc來捕獲它。

回答

8

你缺少一個電話SetErrorMode()

SetErrorMode(SEM_NOGPFAULTERRORBOX); 

這是必要的,以防止OS 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()的作用是在整個運行過程中的所有線程全局。

0

有趣。

如果您在Delphi IDE中運行應用程序(在2007中試用),但如果從命令提示符運行它,則不會調用自定義異常處理程序。

另一個有趣的事情 - 我改變了主程序代碼

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

,發現後,我按Enter鍵(得到一些輸入Readln)時,才顯示該異常消息。因此,當發生異常但處理它時(隱含的try..except包裝所有代碼),不會調用您的處理程序。合理。

必須是這個隱式try..except然後,但我缺乏一個非德爾福調試器在這臺機器上,無法進一步挖掘。也許別人知道答案......

相關問題