Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как выгрузить DLL из Windows?

5.4K
13 декабря 2003 года
PdAndrey
8 / / 02.12.2003
Я использую FreeLibrary, но она не работает.
Библиотеки не выгружаются.
Мне нужно чтобы DLL была свободна и я мог ее убить или переместить.
Подскажите пожалуйста что нужно сделать.
239
13 декабря 2003 года
Dolonet
1.7K / / 20.05.2000
Цитата:
Originally posted by PdAndrey
Я использую FreeLibrary, но она не работает.
Библиотеки не выгружаются.
Мне нужно чтобы DLL была свободна и я мог ее убить или переместить.
Подскажите пожалуйста что нужно сделать.



Перед физическим удалением/переносом надо сделать uninstall библиотеки ил реестра функцией DllUnregisterServer. О ней пишут:

The DllUnregisterServer function removes entries associated with a Cluster Administrator extension DLL from the system registry.

310
13 декабря 2003 года
fellow
853 / / 17.03.2003
FreeLibrary уменьшает счётчик использования DLL вызывающим процессом и выгружает библиотеку при достижении счётчика нуля. Если после вызова FreeLibrary ваша библиотека всё ещё не выгружена, значит для неё несколько раз вызывалась LoadLibrary, соответственно счётчик больше единицы. Такое бывает, если библиотека загружена по ходу инициализации процесса, поскольку зависимость была задана при компоновке, а потом ещё и вручную грузится.
Ещё проверьте легальность передаваемого FreeLibrary аргумента.
5.4K
13 декабря 2003 года
PdAndrey
8 / / 02.12.2003
Цитата:
Originally posted by Dolonet


Перед физическим удалением/переносом надо сделать uninstall библиотеки ил реестра функцией DllUnregisterServer. О ней пишут:

The DllUnregisterServer function removes entries associated with a Cluster Administrator extension DLL from the system registry.




я задавал цикл до 100000 раз, оно все равно не выгружает.
Есть еще идеи?

5.4K
13 декабря 2003 года
PdAndrey
8 / / 02.12.2003
Цитата:
Originally posted by fellow
FreeLibrary уменьшает счётчик использования DLL вызывающим процессом и выгружает библиотеку при достижении счётчика нуля. Если после вызова FreeLibrary ваша библиотека всё ещё не выгружена, значит для неё несколько раз вызывалась LoadLibrary, соответственно счётчик больше единицы. Такое бывает, если библиотека загружена по ходу инициализации процесса, поскольку зависимость была задана при компоновке, а потом ещё и вручную грузится.
Ещё проверьте легальность передаваемого FreeLibrary аргумента.



я задавал цикл до 100000 раз, оно все равно не выгружает.
Есть еще идеи?

310
13 декабря 2003 года
fellow
853 / / 17.03.2003
[COLOR=orangered]Ещё 100001 раз проверьте легальность передаваемого FreeLibrary аргумента.[/COLOR]
310
13 декабря 2003 года
fellow
853 / / 17.03.2003
Тот факт, что библиотека может быть загружена каким-либо процессом, кроме вашего, FreeLibrary не опознаёт и не диагностирует. Таким образом, если ещё кто бы то ни было загрузил DLL и не выгрузил, то ни переместить, ни перезаписать её не удастся.
А кстати, какое значение возвращает FreeLibrary?
5.4K
13 декабря 2003 года
PdAndrey
8 / / 02.12.2003
Цитата:
Originally posted by fellow
Тот факт, что библиотека может быть загружена каким-либо процессом, кроме вашего, FreeLibrary не опознаёт и не диагностирует. Таким образом, если ещё кто бы то ни было загрузил DLL и не выгрузил, то ни переместить, ни перезаписать её не удастся.
А кстати, какое значение возвращает FreeLibrary?



Что значит легальность FreeLibrary?

И как узнать какое значение возвращает FreeLibrary?

310
13 декабря 2003 года
fellow
853 / / 17.03.2003
Цитата:
Originally posted by PdAndrey


Что значит легальность FreeLibrary?

И как узнать какое значение возвращает FreeLibrary?


Легальность [COLOR=orangered]передаваемого FreeLibrary аргумента[/COLOR]
Убедитесь, что аргумент, который вы передаёте функции FreeLibrary, является действительным хендлом загруженного модуля библиотеки, HMODULE.
Узнать же возвращаемое значение легко, обратитесь к справке по Win32 SDK, там сказано, что функция FreeLibrary в случае неудачи возвращает 0.

5.4K
14 декабря 2003 года
PdAndrey
8 / / 02.12.2003
Цитата:
Originally posted by fellow

Легальность [COLOR=orangered]передаваемого FreeLibrary аргумента[/COLOR]
Убедитесь, что аргумент, который вы передаёте функции FreeLibrary, является действительным хендлом загруженного модуля библиотеки, HMODULE.


Не понял я абсолютно этой фразы. я использую HINSTANCE. обьясните пожалуйста. Или, есть ли у вас аська, или что-то в этом духе, где можно в реальном времени пообщатся с вами?
Значение действительно у меня возвращает 0. почему?
ВЫ поняли что мне нужно сделать? мне нужно каким-то мокаром переместить DLL которое загружена виндой в память. Получается мне надо ее выгрузить, а потом переместить, и опять загрузить. Может есть возможность убрать с реестра какие-то данные связанные с этой ДЛЛ?
Скажите пожалуйста как мне заставить чтобы винда забыла про этот файл?! должно же быть команда которая вырубает все проги которые используют этот ДЛЛ, и выгружает его из памяти!
Да кстати, я пишу на С++ Builder.

310
14 декабря 2003 года
fellow
853 / / 17.03.2003
Насколько я понял, то, что Вы пытаетесь сделать, напоминает установку новой версии системной DLL при инсталляции приложения. Предположим, DLL может быть загружена в адресное пространство нескольких процессов, причём заранее неизвестно каких именно. В этом случае выгрузить её функцией FreeLibrary нельзя, т.к. она может выгрузить только те DLL, которые были загружены приложением, в котором вызывается FreeLibrary. Например, Ваша программа стартует, показывает окно TipOfTheDay, после чего пытается загрузить DLL, содержащую изображения игральных карт, CARDS.DLL:
 
Код:
HINSTANCE hcardsdll = ::LoadLibrary("cards.dll");
if(hcardsdll==0)
 {
  //обработка ситуации, когда карты не загружены
 }

Что именно происходит при загрузке, можно прочитать в справке по Win32 SDK или в MSDN, в общих же чертах при первой загрузке вызывается функция DllEntryPoint (или DllMain, как её ни назови) из загружаемой DLL, и если она вернёт нулевое значение, то LoadLibrary также вернёт ноль, что и будет свидетельствовать о сбое при загрузке. При успешной загрузке будет также увеличен счётчик ссылок на загруженную DLL. Этот счётчик "принадлежит" вызвавшему LoadLibrary процессу, и не имеет никакого отношения к другим процессам, загрузившем данную библиотеку.
После того, как библиотека использована и больше не нужна, приложение вызывает функцию FreeLibrary и передаёт ей в качестве аргумента то значение, которое было возвращено из LoadLibrary:
 
Код:
bool result = ::FreeLibrary(hcardsdll);
if(!result)
 {
  //выгрузка неуспешна
 }

Эта функция действует в противополжном направлении, сначала уменьшая счётчик ссылок на загруженную DLL, и выгружает её при достижения счётчиком нулевого значения. Таким образом, если процесс вызывал LoadLibrary для одной и той же библиотеки несколько раз, то значение счётчика ссылок будет больше единицы. Более того, библиотека могла быть загружена при старте приложения, если его зависимость от библиотеки была задана на этапе компоновки, как обычно происходит в Билдере при использовании динамической RTL. В этом случае, счётчик ссылок для этой библиотеки уже будет равен единице, до первого вызова LoadLibrary, если таковой будет, по недосмотру или прихоти программиста, сделан. И снова, FreeLibrary работает только для того процесса, который её вызвал, не затрагивая другие.
Когда пользователь запускает инсталляцию, та иногда содержит системные DLL, имеющие более свежую версию, чем существующие в системе. Классический образец - COMCTL32.DLL, которая перезаписывается едва ли не всякий раз при установке очередного шедевра "готического" программирования от Microsoft. В более новых операционных системах, win2k и XP, инсталлятор может и сразу перезаписать DLL, даже если в текущий момент она находится в использовании. Насчёт этого посмотрите MSDN, я тут не вполне компетентен. Раньше же, для '95/'98/'NT, инсталлятор вызвал какую-либо функцию из так называемого Setup API, или формирующую очередь файловых операций (SetupOpenFileQueue, SetupQueueCopySection, SetupCommitFileQueue), или прямого копирования файла (SetupInstallFileEx). В зависимости от занятости DLL файл мог быть перезаписан сразу, или возвращался признак занятости, в этом случае перезапись откладывалась на момент следующей перезагрузки Windows, которая вызывалась, как правило, в конце процедуры инсталляции. В этом случае пользователь иногда успевал увидеть надпись на текстовом экране "Updating system files" или что-то в этом роде, пока операционка не запускалась снова в графическом режиме. Информацию по этим функциям смотрите в подсказке по Win32 SDK, идущей в комплекте с Билдером, или в MSDN.
5.2K
16 декабря 2006 года
SerMax
96 / / 04.11.2006
Цитата: fellow
Насколько я понял, то, что Вы пытаетесь сделать, напоминает установку новой версии системной DLL при инсталляции приложения. Предположим, DLL может быть загружена в адресное пространство нескольких процессов, причём заранее неизвестно каких именно. В этом случае выгрузить её функцией FreeLibrary нельзя, т.к. она может выгрузить только те DLL, которые были загружены приложением, в котором вызывается FreeLibrary.



У меня такая проблема! Как выгрузить dll из процессов, когда основная программа уже закрылась, выгрузила библиотеку из своего АП..а в другие процессы до сих пор пользуются библиотекой !!

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог