2013-03-13 4 views
5

Приложение My Delphi (с использованием XE3) должно обрабатывать исключение EInOutError, возникающее при удалении порта USB-Serial. Приложение используется в тестовой среде, поэтому не может полагаться на оператора, чтобы нажать кнопку «ОК», чтобы закрыть диалоговое окно «Ошибка приложения».Как обрабатывать исключение, когда USB-последовательный порт удален неожиданно?

Я попытался следующие:

  • «попробовать .. кроме» метод - это не улавливает эти исключения. Я думаю, что это не работает, потому что исключение не вызвано кодом в блоке «try». Это похоже на исключение «системного уровня» более низкого уровня.

  • Я пробовал добавить компонент "ApplicationEvents" в свою форму. Метод OnException улавливает исключение «Custom», генерируемое моим приложением, но не исключение на системном уровне.

  • Я также попытался добавить глобальный крючок исключения (как описано в Is it possible to have a global exception hook?). Это отчасти работает - это позволяет мне делать вещи до диалоговое окно «Ошибка приложения», но не останавливает диалог с ошибкой.

Буду признателен за любые идеи!

+0

Если попробовать, за исключением блока не отлов исключения, то либо исключение не происходит, когда вы думаете, что это, это быть перехвачены и обработаны другим кодом раньше, чем вы» re пытается поймать его, или это не исключение. Поскольку вы не можете его поймать, как вы знаете, что это исключение EInOutError? –

+0

Вы попадаете в сообщение WM_DEVICECHANGE с типом DBT_DEVICEREMOVECOMPLETE и DBT_DEVTYP_PORT, когда USB-Serial удален? – MBo

+0

Привет, Роб, я получаю диалоговое окно под названием «Ошибка приложения», которое появляется. Сообщение внутри диалогового окна «Исключение EInOutError в модуле Project1.exe в 001C7052». Это приложение работает вне IDE/отладчика. – Nigel

ответ

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

+0

Это довольно странно. Я использую http://sourceforge.net/projects/comport/ и не вижу таких ошибок после удаления порта. Может быть, ваша библиотека выполняет непрерывный опрос портов?Вы можете проверить это с помощью http://technet.microsoft.com/en-us/sysinternals/bb896644.aspx – MBo

Смежные вопросы