Исключения не отображаются при запуске приложения Delphi

Я запускаю пример приложения для модема Delphi 10.2 Tokyo.

C:\Users\Mike\Documents\Embarcadero\Studio\Projects\Tethering\PhotoWall\Mobile

При нормальной работе на Windows и iPad приложение работает без ошибок, но не работает.

При запуске с отладчиком (как в Windows, так и в iPad) он получает сообщения об ошибках, подобные этим:

Уведомление об исключении отладчика

Project MobilePhotoApp поднял класс исключения EIdSocketError с сообщением «Ошибка сокета № 48. Адрес уже используется».

Project MobilePhotoApp поднял класс исключения EIdCouldNotBindSocket с сообщением «Не удалось связать сокет. Адрес и порт уже используются.'.

Как заставить приложение показывать эти ошибки при нормальном развертывании без отладчика?введите здесь описание изображения


person Mike at Bookup    schedule 06.11.2017    source источник
comment
Возникают ли эти исключения при запуске в отладчике, появляются диалоговые окна ошибок?   -  person nil    schedule 06.11.2017
comment
Вы должны получить их, если только вы не захватываете и не проглатываете их с помощью блока try..except или в обработчике событий Application.OnException.   -  person GolezTrol    schedule 06.11.2017
comment
Да, эти исключения возникают при запуске в отладчике. Диалоговые окна ошибок не появляются при нормальном запуске.   -  person Mike at Bookup    schedule 06.11.2017
comment
Я думаю, вам нужно изменить код, который обрабатывает эти исключения. Мы не можем видеть ваш код.   -  person David Heffernan    schedule 06.11.2017
comment
У источника есть только две пары try... finally, которые освобождают объект. Я согласен с тем, что я должен получать эти ошибки, если они не перехвачены и не проигнорированы попыткой... за исключением. Вот почему я разместил этот вопрос.   -  person Mike at Bookup    schedule 06.11.2017
comment
Вы можете увидеть код, если у вас Delphi 10.2. Он не был изменен.   -  person Mike at Bookup    schedule 06.11.2017
comment
Это не совсем то, как мы катимся здесь. Вопрос должен стоять отдельно. Нам понадобится минимальный воспроизводимый пример, чтобы этот вопрос был здесь корректным.   -  person David Heffernan    schedule 06.11.2017
comment
Вопрос должен стоять отдельно. Однако для этого требуется использовать Delphi, который поставляется с этим (относительно) минимальным полным и проверяемым примером.   -  person Mike at Bookup    schedule 06.11.2017
comment
Похоже, он пытается использовать порт 2020. У вас уже должно быть другое приложение, использующее этот порт. Как ни странно, это исходит от Indy, но я ничего не вижу ни в одном из этих примеров приложений, использующих Indy.   -  person Jerry Dodge    schedule 06.11.2017
comment
Я специально спрашивал, потому что «Уведомление об исключении отладчика», как в вашем вопросе, не появляется, это что-то, что используется внутри отладчика (и может быть отключено для типов исключений). Если исключение, вызвавшее это внутреннее диалоговое окно уведомления отладчика, не обрабатывается, оно обычно вызывает фактическое диалоговое окно ошибки, которое может видеть пользователь. А тут как бы не хватает.   -  person nil    schedule 06.11.2017
comment
На самом деле кажется, что IPPeer внутри использует Indy. Кроме того, я также не могу найти ссылку на порт 2020.   -  person Jerry Dodge    schedule 06.11.2017
comment
На этом компьютере используется пробная версия Delphi без исходного кода. Возможно, это нормальное поведение для исключений, когда источник кода, вызывающего исключение, недоступен?   -  person Mike at Bookup    schedule 06.11.2017
comment
Нашел. Похоже, что библиотека привязки в Delphi жестко запрограммировала этот порт, а также некоторые другие. System.Tether.NetworkAdapter имеет TTetheringNetworkAdapterCommon, который ссылается на эти номера портов.   -  person Jerry Dodge    schedule 06.11.2017
comment
Я использую только Delphi 10.2 (пробная версия) на этом компьютере с Windows 10, и ничего не установлено, кроме EditPad Lite. Я не знаю, что будет использовать этот порт. (Я также совсем не знаком с сетями, поэтому я действительно не знаю, что такое порт.) Есть ли способ изменить эти порты без доступа к исходному коду?   -  person Mike at Bookup    schedule 06.11.2017
comment
Я полагаю, что абсолютно невозможно использовать эту библиотеку привязки в ее текущем состоянии в вашем сценарии, поэтому +1 к вашему вопросу. Кто-то принял несколько неверных решений при его разработке.   -  person Jerry Dodge    schedule 06.11.2017
comment
Пожалуйста, не публикуйте изображения вашего кода и сообщения об ошибках. Этот метапост содержит список многих причин, по которым изображения кода бесполезны для нас. минимальный воспроизводимый пример состоит из кода в вашем сообщении, правильно отформатированного как такового. Сообщения об ошибках/исключениях также следует копировать и вставлять как текст; при открытом одном из диалоговых окон исключений нажатие Ctrl+C скопирует текстовую версию диалогового окна в буфер обмена.   -  person Ken White    schedule 06.11.2017
comment
Отладчик видит все исключения раньше, чем приложение. Пользователь приложения видит только те исключения, которые возникают в контексте потока пользовательского интерфейса и не перехватываются кодом пользовательского интерфейса, но перехватываются обработчиками по умолчанию внутри RTL. Если отладчик показывает исключение, которое не отображается пользователю приложения, это означает, что исключение где-то перехвачено приложением. В этом случае, если ваш собственный код не видит исключение сокета, это означает, что оно перехватывается внутренней библиотекой привязки. Я предлагаю вам настроить отладчик так, чтобы он игнорировал это исключение.   -  person Remy Lebeau    schedule 06.11.2017
comment
Служба поддержки модема пробует порты в диапазоне 2020–2039 для менеджера один за другим, пока не найдет тот, который можно использовать. Для каждого используемого порта будет вызываться исключение, которое вы видите, однако приложение обрабатывает исключение, поэтому вы не видите его в приложении.   -  person Dave Nottage    schedule 07.11.2017


Ответы (2)


С помощью ряда участников в комментариях, это то, что кажется ответом.

Исключения, вероятно, обрабатываются внутри сетевой библиотеки, поскольку она ищет свободный порт.

Я предположил, что исключения объясняют проблему с отсутствием привязки в Windows 10. Однако мобильное приложение успешно соединяется (с компаньоном на рабочем столе, работающем либо на компьютере с Windows 7, либо на Macintosh), когда мобильное приложение запускается на Android или iPad. Проблема с отсутствием сопряжения, скорее всего, связана с брандмауэром на компьютере с Windows 10.

В этом вопросе я спросил, как заставить Windows 10 или ее брандмауэр предоставить доступ к приложению Delphi для привязки: Приложения Delphi не будут привязаны к Windows 10

person Mike at Bookup    schedule 07.11.2017
comment
Выяснилось, что McAfee Internet блокирует приложения для модема Delphi. После удаления McAfee Windows запросила исключение брандмауэра и разрешила сопряжение приложений для модема. Ни McAfee, ни приложения для модема Delphi не отображали сообщения об ошибке при сбое сопряжения. - person Mike at Bookup; 13.11.2017

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

Основываясь на именах исключений, я предполагаю, что они исходят из сетевой библиотеки Indy. Indy — это сторонняя сетевая библиотека, поставляемая с Delphi. Большинство компонентов Indy спроектированы таким образом, чтобы никогда не вызывать никаких исключений, поскольку они обрабатываются внутри.

Как правило, вам следует проверить документацию компонента, чтобы увидеть правильный способ обработки ошибок. Но это может быть проблематично для вас, поскольку компоненты Indy используются компонентами Tethering внутри, что очень все усложняет.

В любом случае наиболее вероятной причиной того, что пример приложения не может подключиться, является тот факт, что компоненты Indy быстро вызывают внутреннее исключение и отказываются от попыток подключения, если они заблокированы брандмауэром. На самом деле это часто происходит так быстро, что ваш брандмауэр даже не спросит вас, хотите ли вы разрешить вашей программе устанавливать это сетевое соединение или нет.
Это одна из причин, почему мне не нравится работать с компонентами Indy. так как мой Eset Smart Security никогда не показывает диалоговое окно подтверждения достаточно быстро, чтобы я мог установить сетевое соединение. Поэтому мне нужно добавить это приложение в исключение брандмауэра, прежде чем я попытаюсь что-либо сделать с компонентами Indy.

person SilverWarior    schedule 06.11.2017
comment
Большинство компонентов Indy сконструированы таким образом, что никогда не вызывают никаких исключений, поскольку они обрабатываются внутри. Я считаю это утверждение ложным. Конечно, они вызывают исключения. Вопрос в том, обрабатываются ли эти исключения или нет. - person Jerry Dodge; 07.11.2017
comment
Я запустил это мобильное приложение Photowall для модема на iPad с помощью отладчика. Я получаю результаты, аналогичные ошибкам из Windows 10. Означает ли это, что у iPad те же проблемы, что и у Windows? Я до сих пор не понимаю, почему исключения появляются при запуске в отладчике, а не при обычном запуске. - person Mike at Bookup; 07.11.2017
comment
@MikeatBookup Честно говоря, я не знаю, может ли причина для приложения Photowall быть той же, что и в Windows, потому что лично у меня нет опыта в мобильной разработке и у меня нет возможности протестировать его. Таким образом, вам придется создать собственное небольшое тестовое приложение, используя компонент Indy UDP, который пытается работать с одним и тем же диапазоном портов, чтобы увидеть, будет ли отладчик захватывать те же исключения. - person SilverWarior; 07.11.2017
comment
@MikeatBookup Что касается того, почему исключения все еще появляются, когда приложение запускается через отладчик. Отладчик всегда будет перехватывать любые исключения независимо от того, обрабатываются они приложением или нет. На самом деле код для обработки перехваченных исключений запустится только после того, как вы нажмете кнопку «Продолжить» или попытаетесь выполнить шаг вперед в Delphi после обнаружения исключения. Единственный способ для отладчика не захватывать определенные исключения — это приказать ему игнорировать определенные типы исключений. И вы можете сделать это, изменив параметры Delphi в Tools->Options->Debugger Options->Language Exceptions. - person SilverWarior; 07.11.2017