Как использовать dll вне системного пути

Я сделал приложение, которое использует библиотеки DLL openssl (libeay32.dll и ssleay32.dll). Их можно использовать самостоятельно, я не вызываю библиотеки напрямую.

Простейший обходной путь, который я нашел, чтобы избежать установки установщика (я просто делаю exe-файл, и меня устраивает этот подход), заключается в следующем:

  1. поместите dll как ресурсы exe
  2. при запуске программы извлекаю их в папку exe
  3. exe использует их

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

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

Кто знает, как заставить Indy использовать библиотеки DLL в моем временном пути? (например, "временная регистрация dll")


person LaBracca    schedule 07.11.2012    source источник
comment
один из способов: посмотрите, как Indy загружает эти библиотеки DLL, измените эти файлы * .pas и поместите их в каталог вашего проекта, и тогда вы в значительной степени выберетесь из леса.   -  person    schedule 07.11.2012
comment
@ComputerSaysNo Я использую Indy как черный ящик, я не ленив, но помню, как однажды я прочитал о возможности использования dll вне системного пути, как бы зарегистрировав ее при запуске программы. Это было бы лучше для меня. Может быть, тот факт, что Инди, а не я использую эти dll, не важен.   -  person LaBracca    schedule 07.11.2012
comment
Я думаю, вам следует изменить свой вопрос ... другой способ - оставить функциональность как есть и просто скрыть файлы, а затем удалить их при закрытии приложения.   -  person    schedule 07.11.2012
comment
P.S. вы также можете попробовать другой подход, если приложения нет во временной папке, скопируйте себя туда, запустите и закройте, тогда все будет работать так, как вы этого хотите.   -  person    schedule 07.11.2012
comment
Если вы загрузили библиотеки DLL с помощью LoadLibrary явно, как только вы записали их во временную папку, разве это не удовлетворило бы более поздний вызов LoadLibrary?   -  person frogb    schedule 07.11.2012
comment
@frogb Да, это сработает. Кроме того, я думаю, вы должны опубликовать это в качестве ответа, это, вероятно, лучшее решение.   -  person Ondrej Kelle    schedule 07.11.2012
comment
Еще одна идея: если вы используете SetEnvironmentVariable и измените переменную PATH, чтобы указать на вашу папку с DLL ... не будет ли loadLibrary обманут, чтобы использовать новый путь? Не проверенная идея :)   -  person iPath ツ    schedule 07.11.2012
comment
@DavidHeffernan Если lpFileName не включает путь и имеется более одного загруженного модуля с одинаковым базовым именем и расширением, функция возвращает дескриптор модуля, который был загружен первым.   -  person Ondrej Kelle    schedule 07.11.2012
comment
Оба решения интересны :) Это обычная проблема Indy при использовании SSL :)   -  person iPath ツ    schedule 07.11.2012
comment
@TOndrej Ага, сегодня для меня скромный пирог на обед! Удаляю свои фиктивные комментарии.   -  person David Heffernan    schedule 07.11.2012
comment
@TOndrej Спасибо за вашу поддержку: мой первоначальный комментарий был вопросом!   -  person frogb    schedule 07.11.2012
comment
@iPath Это тоже сработает. (Я это тестировал.)   -  person Ondrej Kelle    schedule 07.11.2012
comment
Как пользователи смогут устанавливать обновленные версии OpenSSL DLL? Когда будут обнаружены проблемы с безопасностью и появится новая версия OpenSSL, обычные библиотеки DLL можно будет заменить намного проще и быстрее.   -  person mjn    schedule 08.11.2012


Ответы (3)


Загрузите библиотеки DLL самостоятельно с помощью LoadLibrary как можно скорее так как вы записали их во временную папку.
Это заставит Indy LoadLibrary использовать ваши библиотеки DLL, когда они им нужны:

Если lpFileName не включает путь и имеется более одного загруженного модуля с одинаковым базовым именем и расширением, функция возвращает дескриптор модуля, который был загружен первым.

person frogb    schedule 07.11.2012
comment
Я просто взял эту отличную идею и применил ее к своему интерфейсному модулю .net p / invoke, который обеспечивает доступ к моей собственной библиотеке. Это упрощает связывание. Хороший. - person David Heffernan; 07.11.2012
comment
Наконец, я использовал технику, предложенную в этом ответе (LoadLibrary), которая позволила мне добиться успеха без необходимости обновлять Indy, что это болезненная вещь (каждый раз, когда я пытался обновить, я терпел неудачу: слишком много ручных действий). - person LaBracca; 19.02.2015

Если вы используете последнюю версию Indy 10, в модуле IdSSLOpenSSLHeaders есть общедоступная функция IdOpenSSLSetLibPath(), которая сообщает Indy, в какой пользовательской папке искать библиотеки DLL OpenSSL:

procedure IdOpenSSLSetLibPath(const APath: String);
person Remy Lebeau    schedule 07.11.2012
comment
Спасибо, в модуле IdSSLOpenSSLHeaders у меня нет IdOpenSSLSetLibPath (), значит, мне нужно обновить? У меня 10.5.8.0 - person LaBracca; 08.11.2012
comment
Да, вам нужно будет обновить, если вы не исправите существующую версию вручную. - person Remy Lebeau; 08.11.2012
comment
@RemyLebeau Я обновляю, но стоит ли доверять версии SVN? Какая это версия? Благодарность - person LaBracca; 18.03.2014
comment
Текущая версия магистрали - 10.6.0 rev 5114. - person Remy Lebeau; 18.03.2014
comment
@RemyLebeau, спасибо, я дважды отправляю сообщения, в любом случае я действительно застрял, я не помню, как мне удалось обновить indy в соответствии с инструкциями stackoverflow.com/questions/3204601/ разве нет вовремя инструкции по обновлению? сейчас я даже не могу найти пакеты. - person LaBracca; 19.03.2014
comment
Обновление: мне удалось открыть пакеты, но я получил ошибку компиляции: [Неустранимая ошибка DCC] IdGlobal.pas (1953): F2063 Не удалось скомпилировать использованный модуль «IdException.pas». Я должен дождаться завтрашней сборки? - person LaBracca; 19.03.2014
comment
инструкции по установке доступны на веб-сайте Indy. Не удалось скомпилировать использованный модуль ... - это побочный эффект предыдущих ошибок компиляции. Устранение ошибок компилятора в это обсуждение не входит. Задайте для него новый вопрос. - person Remy Lebeau; 19.03.2014

Вы можете использовать SetDllDirectory для управления порядком поиска DLL.

person David Heffernan    schedule 07.11.2012
comment
+1, но, безусловно, изменение исходных текстов Indy должно быть последним средством (именно это я и сделал со своим приложением). Я предпочитаю ваше решение, которое, на мой взгляд, является правильным путем. - person kobik; 07.11.2012
comment
@kobik Поразмыслив, согласен. Мне действительно очень нравится решение frogb, теперь, когда я убежден, что оно работает. У меня было неправильное понимание того, как работает LoadLibrary. - person David Heffernan; 07.11.2012