2013-03-13 29 views
5

我的Delphi應用程序(使用XE3)需要處理移除USB串行端口時發生的EInOutError異常。應用程序在測試環境中使用,因此不能依賴操作員單擊「確定」按鈕關閉「應用程序錯誤」對話框。如何處理意外移除USB串口的異常?

我曾嘗試以下:

  • 「嘗試..除」法 - 這並不捕獲這些異常。我認爲這不起作用,因爲異常不是由「try」塊中的代碼引起的。它似乎是一個較低級的「系統級」異常。

  • 我試着在窗體中添加一個「ApplicationEvents」組件。 OnException方法捕獲由我的應用程序生成的「自定義」異常,但不捕獲系統級異常。

  • 我也嘗試添加全局異常掛鉤(如Is it possible to have a global exception hook?中所述)。這部分工作 - 它允許我在之前的應用程序錯誤對話框中執行,但不會停止錯誤對話框。

我將不勝感激任何想法!

+0

如果try-except塊未捕獲異常,那麼無論是異常沒有發生,你認爲它是,它被抓住了,其它的代碼比你早處理」試圖抓住它,或者它不是一個例外。既然你無法捕捉它,你怎麼知道這是一個EInOutError異常? – 2013-03-13 12:26:21

+0

當USB串行被刪除時,您是否使用DBT_DEVICEREMOVECOMPLETE類型和DBT_DEVTYP_PORT設備類型捕獲消息WM_DEVICECHANGE? – MBo 2013-03-13 12:58:29

+0

嗨,羅布,我彈出一個標題爲「應用程序錯誤」的對話框。對話框中的消息是001C7052模塊Project1.exe中的Exception EInOutError。這是在IDE /調試器之外運行應用程序。 – Nigel 2013-03-13 14:09:53

回答

3

由於USB-Com移除引起的異常非常討厭。所以我建議消除他們的大部分原因。

您必須處理Windows消息WM_DEVICECHANGE並檢測端口刪除。然後設置特殊標誌,並且不要對帶有此標誌的端口進行任何操作!如果再次插入USB-Com,則重新連接串行端口。一些代碼,以幫助:

const 
     DBT_DEVICEARRIVAL = $8000; 
     DBT_DEVICEREMOVECOMPLETE = $8004; 
     DBT_DEVICEQUERYREMOVE = $8001; 
     DBT_DEVTYP_PORT = 3; 

    type 
     PDevBroadcastHdr = ^TDevBroadcastHdr; 
     TDevBroadcastHdr = packed record 
     dbcd_size: DWORD; 
     dbcd_devicetype: DWORD; 
     dbcd_reserved: DWORD; 
     end; 

     PDEV_BROADCAST_PORT = ^TDEV_BROADCAST_PORT; 
     TDEV_BROADCAST_PORT = packed record 
     dbcp_size: DWord; 
     dbcp_devicetype: DWord; 
     dbcp_reserved: DWord; 
     dbcp_name: array[0..MAX_PATH] of Char; 
     end; 

    ... 
    procedure WMDEVICECHANGE(var Msg: TMessage); message WM_DEVICECHANGE; 
    ... 

procedure TForm1.WMDEVICECHANGE(var Msg: TMessage); 
var 
    prt: PDEV_BROADCAST_PORT; 
    s: string; 
begin 

    if Msg.wparam = DBT_DEVICEREMOVECOMPLETE then 
    if PDevBroadcastHdr(Msg.lParam)^.dbcd_devicetype = DBT_DEVTYP_PORT then 
     begin 

     b_PortRemoved := True; //check this flag before each operation with port. 


     prt := PDEV_BROADCAST_PORT(PDEV_BROADCAST_PORT(Msg.lParam)); 
     s := prt.dbcp_name; 
     ShowMessage('ComPort ' + s + ' has been removed. What can I do?'); 
    end; 

    if Msg.wparam = DBT_DEVICEARRIVAL then 
    if PDevBroadcastHdr(Msg.lParam)^.dbcd_devicetype = DBT_DEVTYP_PORT then begin 
     // USB-COM plugged, you can find it and make some reinitialisation 
    end; 


end; 
+0

感謝您的示例代碼!即使我沒有「打開」端口,它也能正確檢測到正在插入和移除的端口。但是,一旦端口被刪除,我仍然會得到應用程序錯誤(儘管我沒有寫任何東西)。 – Nigel 2013-03-13 14:51:21

+0

這很奇怪。我使用http://sourceforge.net/projects/comport/,並且在刪除端口後不會看到這樣的錯誤。可能是,您的圖書館執行連續的端口輪詢?您可以使用http://technet.microsoft.com/en-us/sysinternals/bb896644.aspx進行檢查 – MBo 2013-03-13 16:42:21