USB转串口意外拔出时出现异常如何处理?

问题描述 投票:0回答:3

我的 Delphi 应用程序(使用 XE3)需要处理移除 USB 串行端口时发生的 EInOutError 异常。该应用程序是在测试环境中使用的,因此不能依赖操作员单击“确定”按钮来关闭“应用程序错误”对话框。

我尝试过以下方法:

  • “try .. except”方法 - 这不会捕获这些异常。我认为这不起作用,因为异常不是由“try”块中的代码引起的。似乎是较低级别的“系统级”异常。

  • 我尝试在表单中添加“ApplicationEvents”组件。 OnException 方法捕获我的应用程序生成的“自定义”异常,但不是系统级异常。

  • 我还尝试添加全局异常挂钩(如是否可以有全局异常挂钩?中所述)。这部分有效 - 它允许我在“应用程序错误”对话框之前执行操作,但不会停止错误对话框。

如有任何想法,我将不胜感激!

delphi exception
3个回答
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
投票
我在使用 Delphi Tokyo 和 AsyncPro VCL 2022.06 时遇到了同样的问题,并找到了一个非常简单的解决方案。存在一个全局异常处理程序变量 GShowExceptionHandler,您可以使用它来避免错误消息。您可以在 AwUser.pas 中找到它。这是一个如何使用它的小例子。希望这对 Borland Builder 也有帮助。

uses AwUser; type TReaderException = procedure(ExceptObject: TObject; ExceptAddr: Pointer) of object; type TForm1 = class(TForm) private FOnReaderException:TReaderException; procedure OnReaderException(ExceptObject: TObject; ExceptAddr: Pointer); end; procedure TForm1.FormCreate(Sender: TObject); begin FOnReaderException:=OnReaderException; // Set global exception handler for AsyncPro GShowExceptionHandler:=@FOnReaderException; end; procedure TMainWin.OnReaderException(ExceptObject: TObject; ExceptAddr: Pointer); begin // do your own exception handling end;
    

0
投票
我在 Delphi 12 Athens 上使用 ApdTomPort,当设备与 USB 端口断开连接时,问题始终是相同的 eInOutError

谢谢安德烈亚斯提供的解决方案!

© www.soinside.com 2019 - 2024. All rights reserved.