Windows 2008 и неправильная загрузка BPL

У меня есть приложение, созданное с помощью пакетов времени выполнения. Когда исполняемый файл запускается, он автоматически загружает необходимые пакеты (.bpl).

Недавно мы установили сервер Windows 2008 R2 для использования в качестве служб терминалов.

Мы храним некоторые старые скомпилированные версии нашего приложения по разным путям, например:

c:\app\version_1\common.bpl
c:\app\version_1\app.exe

c:\app\version_2\common.bpl
c:\app\version_2\app.exe

Common.bpl — это пакет времени выполнения, от которого зависит app.exe.

ЭТА ПРОБЛЕМА:

Я запускаю "c:\app\version_2\app.exe", а загружается "c:\app\version_2\common.bpl". Когда я запускаю "c:\app\version_1\app.exe", он загружает НЕПРАВИЛЬНЫЙ bpl (из версии_2).

Путь "c:\app\version_2\" не входит в путь системного поиска.

На сервере Windows2003 этой проблемы не возникает.

Что я могу сделать, чтобы решить эту проблему?

Спасибо!


Я скачал Process Explorer (Microsoft sysinternals) и проверил загруженные модули каждого исполняемого файла, все они правильные!

Но я заметил другую проблему. После запуска второй версии возникает ошибка «запись не найдена», сообщающая мне, что не удалось найти точку входа инициализации модуля, который существует только в одной из версий.

Что-то очень странно. ProcessExplorer сообщает мне, что процесс загружает правильные модули, но когда они работают, этого не происходит.

Кажется, приложения совместно используют загруженные модули.


РЕШЕНО

Был MouseHook с использованием FindVCLWindow, он генерировал AV.

Извините за неудобства, ребята, и спасибо!


person Beto Neto    schedule 10.10.2012    source источник
comment
трудно представить, как просматривается файл в той же папке, что и исполняемый файл   -  person David Heffernan    schedule 11.10.2012
comment
Вы уверены, что это не другая функция виртуализации файлов в Windows Terminal Services? Другими словами, то, что, по вашему мнению, происходит, на самом деле не происходит. Чтобы быть уверенным, УДАЛИТЕ BPL из версии_2 и посмотрите, не ошибся ли он. Если это так, то у вас есть еще одна кешированная/виртуализированная копия этой DLL где-то в ДРУГОМ каталоге на вашем пути.   -  person Warren P    schedule 11.10.2012
comment
@David - это плохой, но стандартный выбор для Windows, когда вы не указываете полный путь к DLL. Точно так же, как Excel не может открывать файлы с одинаковыми именами из разных папок.   -  person Arioch 'The    schedule 11.10.2012
comment
@Arioch Это совершенно другое. Ограничение Excel — это просто плохой дизайн приложения. Ничего общего с относительными путями. Путь поиска Windows DLL имеет каталог exe в верхней части списка искомых мест. Это отличный дизайн. Это позволяет изолировать и дает разработчикам контроль.   -  person David Heffernan    schedule 11.10.2012
comment
@WarrenP, здесь может быть правильно. просто предположение ... также вы встроили манифест UAC в свои EXE-файлы, чтобы избежать визуализации?   -  person kobik    schedule 11.10.2012
comment
У меня нет встроенного манифеста UAC. Как я могу это сделать?! Я использую Делфи 7.   -  person Beto Neto    schedule 11.10.2012
comment
Создайте ресурс манифеста. Используйте Интернет, чтобы решить, что он должен содержать. Скомпилируйте его с помощью brcc32. И свяжите его с $R.   -  person David Heffernan    schedule 11.10.2012
comment
Я думаю, что вам нужно сделать, чтобы избежать виртуализации, это PE-флаг. Проверьте эту ссылку: stackoverflow.com /вопросы/10517022/   -  person Warren P    schedule 11.10.2012
comment
Я голосую за закрытие этого вопроса. Я думаю, вам следует просто удалить его.   -  person kobik    schedule 17.10.2012


Ответы (1)


Если BPL статически связаны с EXE и если version_2 BPL уже находится в памяти при запуске version_1 EXE, Windows будет повторно использовать существующий BPL в памяти, она не будет повторно загружать новую копию другого BPL. . Это задокументированное поведение:

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

При использовании статической компоновки информация о пути отсутствует, поэтому загрузчик ОС должен самостоятельно отключать имена файлов.

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

Перенаправление DLL/COM в Windows

Перенаправление библиотеки динамической ссылки

person Remy Lebeau    schedule 10.10.2012
comment
Вы все неправильно поняли. Здесь есть два разных процесса. Ссылка MSDN относится к модулям, загруженным в вызывающем процессе. Процессы изолированы. Модули, загружаемые одним процессом, не могут влиять на то, какие модули загружаются другим процессом. Представьте себе хаос, если бы это было правдой. Я создаю модуль с именем user32.dll без экспорта, а затем загружаю его в свой процесс. Что происходит, когда начинается следующий процесс? - person David Heffernan; 11.10.2012
comment
@David LoadModule здесь неуместен, правда. Это поведение PE Loader для экономии виртуальной памяти путем не копирования страниц, если это возможно, а обмена ими. Он использовался для внедрения DLL. Мало информации о загрузчике PE, несколько статей в каких-то старых блогах и тому подобное. Но подобное поведение наблюдалось и раньше. Интересно, может ли он включить специально созданный манифест и использовать WinSxS для решения этой проблемы... - person Arioch 'The; 11.10.2012
comment
@Arioch Я понятия не имею, о чем ты говоришь. Никто. Я не говорил о LoadModule и даже не знаю, что это такое. - person David Heffernan; 11.10.2012
comment
@Arioch'The Вы имеете в виду 16-битный LoadModule API? - person David Heffernan; 11.10.2012
comment
я неправильно назвал LoadLibrary. Я помню, что уже загруженная DLL с тем же именем, по крайней мере, была проблемой при связывании статической DLL, хотя сейчас я не помню подробностей - person Arioch 'The; 11.10.2012
comment
@Arioch'The Это было в 16-битные дни. Но все это было исправлено с 32-битной Windows. - person David Heffernan; 11.10.2012
comment
См. раздел Порядок поиска в библиотеке Dynamic-Link. Нужно проверить, зарегистрирована ли common.bpl как KnownDLL в реестре. Это может привести к тому, что несколько приложений в разных папках загрузят один и тот же физический файл. - person Remy Lebeau; 11.10.2012
comment
Интересно, почему вы не удаляете явно неправильный контент? - person David Heffernan; 12.10.2012