Как да използвате dll извън системния път

Направих приложение, което използва openssl dlls (libeay32.dll и ssleay32.dll). Използването им е инди, не извиквам dll директно.

Най-простото заобиколно решение, което намерих, за да избегна инсталатора (просто инсталирам exe и съм добре с този подход) е да:

  1. поставете dll като ресурси на exe
  2. при стартиране на програмата ги извличам в папката exe
  3. exe ги използва

Това е перфектно, но бих искал да подобря подхода, като извлека dll файловете във временна папка, а не в папката exe (която в много случаи е работният плот).

Проблемът е, че не знам как да принудя приложението да използва dll във временната папка, защото сега поведението е: ако dll не са в текущата директория, опитайте да търсите в директориите, дефинирани в системния път.

Кой знае решение за принуждаване на indy да използва dll файловете в моя временен път? (като "временно регистриране на dlls")


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 веднага както сте ги записали във временната папка.
Това ще накара LoadLibrary на Indy да използва вашите 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 в коя персонализирана папка да търси OpenSSL DLL файловете:

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 Fatal Error] IdGlobal.pas(1953): F2063 Не можах да компилирам използваната единица „IdException.pas“, трябва да изчакам утрешната компилация? - person LaBracca; 19.03.2014
comment
инструкциите за инсталиране са налични на уебсайта на Indy. Could not compile used unit... е страничен ефект от по-ранни грешки при компилирането. Отстраняването на грешки при компилатор не принадлежи към тази дискусия. Моля, публикувайте нов въпрос за него. - 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