Столкнулся с простой, на первый взгляд, задачей - надо было определить, что SQL-сервер вообще доступен (прежде чем пытаться к нему подключится, так как у такого подключения большой таймаут). Решил, что сделать это проще всего с помощью команды пинг (ping), и вспомнил, что уже в одном проекте реализовывал подобный функционал с помощью компонента TIdIcmpClient из пакета компонент Indy Clients. Добавил компонент, минимально настроил (фактически только имя сервера прописал). Запускаю - не работает. Выдаёт ошибку:
Project ... raised exception class EIdSocketError with message 'Socket Error # 10013
Access denied.'.
Проверил код - нет, всё правильно. Предположил, что возможно не запускается именно из под Delphi. Запускаю напрямую - тоже не работает. Полез в интернет искать информацию по данной ошибке, а в голове в этом время крутится: "Но раньше, в том проекте, работало же!".
Через некоторое время нахожу информацию, что подобная проблема была раньше с Windows 2000 и решалась запуском программы от имени Администратора (были ещё версии про антивирус и файрвол). Запустил от имени Администратора - работает, но меня это не устроило, так как программа должна запускаться у пользователей с обычными правами. Продолжил поиски, в итоге, нашёл информацию, что при написании компонент Indy были использованы RAW сокеты, которые требуют админские права (вероятнее всего их проверку починили в одном из обновлений Microsoft, поэтому раньше работало, а теперь нет).
Поначалу даже решил отказаться от этой идеи, но потом чувство прекрасного и педантичность (чего это пользователи будут просто так ждать) взяли верх - пришлось искать другое решение. В итоге остановился на решение предложенном в этой статье. При реализации у себя в проекте пришлось немного изменить предложенное решение:
- Пришлось исправить несоответствие типов PChar и PAnsiChar, которые при компиляции выдавала установленная у меня Delphi 2010 (объявление переменой pac: PChar; и присвоение phe := GetHostByName(PChar(AIP));).
- Переделал процедуру TranslateStringToTInAddr в функцию, чтобы возвращать успешность преобразования имени сервера в его IP-адрес (и добавил проверку возвращаемого значения).
В итоге, программа работает так, как планировал - сначала проверяется доступность сервера, и только если он доступен, пробуем подключиться к базе данных.
PS Получившийся у меня файл можно скачать здесь.