Потерянные. История о двух пропавших DLL

Safoyeth 11 Фев 2017

Эта история о том, как заставить gmail отправлять почту из приложения, написанного на Qt. Началось всё с декабря 2016 года, когда я начал писать небольшую программку. В ней не было ничего особенно за исключением одной единственной опции, которая и вызвала к жизни данный эпос. Опция эта — отправка почты через почтовый сервис гугла.

Написав примерно за 3 недели весь функционал, я дошёл до почты. Обгуглив проблему, неожиданно нашёл готовые решения. Собственно здесь можно найти ссылки на оба. Я воспользовался решением от bluetiger9, за что ему отдельное спасибо. Решение отличное и полностью рабочее! Но как обычно есть «НО».

Я успешно реализовал всё, что хотел, скомпилировал обе версии (под 32 и 64 bit) компилятором msvc2015, собрал dll-ки с помощью windeployqt, запустил обе версии (у себя на компьютере!), написал инсталляторы и торжественно всем всё проинсталлировал. Проверил запуск программ на компьютерах пользователей, убедился в работоспособности и готовился уже радоваться тому, какой я красавчик, как началось…

Вдруг оказалось, что почта с компьютеров пользователей не отправляется. Программа выдаёт всем бодренькое «Нет связи с почтовым сервером». Забавно, но на моём компьютере всё работало. Итак, лопату в руки, за раскопки!

Первый подозреваемый — компилятор (у меня всегда так! 🙂 ). Переключаюсь на MinGW, собираю, запускаю. Всё работает. Устанавливаю на другой компьютер — «Нет связи с почтовым сервером». Пробую ставить на разные архитектуры, везде одно и то же. Работает только на двух компьютерах — на моём рабочем и на домашнем, где и велись разработки программы. На каждом из этих компьютеров установлены среди всего прочего Microsoft Visual Studio 2015, Qt 5.7, Python 2.7 (32 bit) c PyQt4, Python 3.4 (64 bit) c PyQt5. На этих двух компьютерах работали все версии.

Поковырявшись несколько часов, я дошёл до второго подозреваемого — собственно проекта SmtpClient-for-Qt, вернее до моей сборки. Форумы Qt, Stackoverflow — все рекомендуют использовать этот проект, но везде подразумевается, что тот, кто его использует, будет иметь прямые руки (хотя, строго говоря, остыв уже от переживаний, мне сложно представить где там можно что-то не так собрать). Переписав несколько раз модуль отправки сообщений, я так и не смог получить ни кода ошибки, ни тем более текста. Каждый раз вместо кода ошибки и текста в QMessagebox::critical приходило пустое сообщение. Отчаявшись, я качнул альтернативный проект. Собрал, запустил, отправил сообщение. Перенёс на другой компьютер, запустил и… и ничего не отправилось.

К счастью, на странице этого проекта я нашёл корень проблемы:

First of all, for the code to run you will need Qt with ssl support compiled within and OpenSSL library

Примерно поняв, в чём проблема, копать стало легче. Для начала в ход пошёл Dependency Walker. Однако и он ничего не показал.

Следующий шаг — установка OpenSSL и попытки разложить её dll-ки в разные места. Как можно догадаться, ничего не изменилось. Дело уже принимало крутой оборот, когда меня осенило использовать Visual Studio для подключения к процессу раскопок.

Итак, запускаю VS, запускаю программу (использовал для опытов 32-битную версию), подключаюсь к процессу и вижу тонну dll, которые загружает моя программа. В поисках счастья перекапываю большинство из них, но ни одна не относится к OpenSSL. Начинаю тыкать по кнопкам в своей программе и вижу как одни dll подгружаются, другие выгружаются из памяти и понимаю, что я осёл. Я совсем забыл, что «d» — это «dynamic», то есть подгружаются они динамически…

Дальше ещё проще. Делаю ошибку в настройках сервера, перезапускаю, нажимаю на кнопку «Отправить письмо», получаю ожидаемое сообщение об ошибке. В это время обшариваю список dll и не могу поверить своим глазам — среди всего прочего вижу C:\Python27\Lib\site-packages\PyQt4\libeay32.dll и дальше C:\Python27\Lib\site-packages\PyQt4\ssleay32.dll. Гуглю и вот оно, счастье:

The Libeay32.dll library is a dynamic link library developed by Support.com, The OpenSSL Project. This library includes important functions that may be needed by programs, games or other basic Windows tools

Со второй вообще всё по имени понятно. Иду в папку, копирую эту сладкую парочку в папку со своей программой, перезапускаюсь, снова отправляю сообщение, смотрю список dll и вижу то, что должен. Переустанавливаю программу на 32-битные машины — всё работает. На 64-битных никаких изменений. Качаю из интернета dll для 64-битных машин (да, я в курсе, что так делать плохо!) и ничего не работает. Разные ошибки, то не найдена точка входа в процедуру, то Access Violation. Но факт, ничего не работает.

Но тут всё просто, на самом деле. Беру 64-битную версию, запускаю, подключаюсь из VS, отправляю письмо, смотрю список модулей и вижу пусть не совсем то, что ожидал, но всё же: C:\Python34\Lib\site-packages\PyQt5\libeay32.dll и C:\Python34\Lib\site-packages\PyQt5\ssleay32.dll.

Дальнейшие действия разрешите не описывать.

Итог: всё работает как часы, всё замечательно, все довольны, а я красавчик. Одно но… А что было бы, если бы у меня не было предустановленных питонов и PyQt?.. Я обязательно это выясню и как-нибудь расскажу!

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.




Добавить комментарий

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: