Re[5]: DLL-Связывание. Поиск DLL. Манифесты.
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 07.10.09 07:59
Оценка:
Здравствуйте, http://alexyv.livejournal.com/, Вы писали:

HAL>И не нужно редактировать манифесты, удаляя publicKeyToken из них, — просто берем и используем.


В дополнение к тому, что написал Юрий Жмеренецкий: если в WinSxS присутстсвует более свежая версия, чем прописано в зависимостях манифеста, то будет использована именно она.
[ posted via RSDN@Home 1.1.4 stable SR1 r568, accompanied by silence ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re[6]: DLL-Связывание. Поиск DLL. Манифесты.
От: Rakafon Украина http://rakafon.blogspot.com/
Дата: 07.10.09 09:06
Оценка: 13 (1)
Здравствуйте, SchweinDeBurg, Вы писали:
SDB>... если в WinSxS присутстсвует более свежая версия, чем прописано в зависимостях манифеста, то будет использована именно она.

... в таком случае, зачем alexyv в своём журнале в записи Side-by-side assemblies и их проблемы приложение, состоящее из нескольких модулей, каждый из которых ссылается на разные версии CRT, конфигурирует с помощью <dll-name>.2.config файлов? Потому что использует private сборку, расположенную в одной с приложением директории, вместо public сборки, установленной в WinSxS?
"Дайте мне возможность выпускать и контролировать деньги в государстве и – мне нет дела до того, кто пишет его законы." (c) Мейер Ансельм Ротшильд , банкир.
Re[7]: DLL-Связывание. Поиск DLL. Манифесты.
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 07.10.09 09:16
Оценка:
Здравствуйте, Rakafon, Вы писали:

R>... в таком случае, зачем alexyv в своём журнале в записи Side-by-side assemblies и их проблемы приложение, состоящее из нескольких модулей, каждый из которых ссылается на разные версии CRT, конфигурирует с помощью <dll-name>.2.config файлов? Потому что использует private сборку, расположенную в одной с приложением директории, вместо public сборки, установленной в WinSxS?


Я, честно говоря, этот пост вижу впервые, поэтому сейчас ответить затрудняюсь, надо будет поэкспериментировать.
[ posted via RSDN@Home 1.1.4 stable SR1 r568, accompanied by silence ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re[6]: DLL-Связывание. Поиск DLL. Манифесты.
От: alexyv http://alexyv.livejournal.com/
Дата: 07.10.09 10:52
Оценка:
Здравствуйте, SchweinDeBurg, Вы писали:

SDB>Здравствуйте, http://alexyv.livejournal.com/, Вы писали:


HAL>>И не нужно редактировать манифесты, удаляя publicKeyToken из них, — просто берем и используем.


SDB>В дополнение к тому, что написал Юрий Жмеренецкий: если в WinSxS присутстсвует более свежая версия, чем прописано в зависимостях манифеста, то будет использована именно она.


При условии, что установлены policy-файлы, перенаправляющие старые версии на новые.

В Visual Studio есть Merge-модули для Windows Installer, и в них сами библиотеки и policy-файлы разделены на два разных модуля. Таким образом, библиотеки более новой версии могут быть установлены в WinSxS, но старые версии перенаправляться на эту новую не будут, если *Policy-*.msm не был включен в инсталляционный пакет.
Re[7]: DLL-Связывание. Поиск DLL. Манифесты.
От: Юрий Жмеренецкий ICQ 380412032
Дата: 07.10.09 11:16
Оценка:
Здравствуйте, Rakafon, Вы писали:

R>Здравствуйте, SchweinDeBurg, Вы писали:

SDB>>... если в WinSxS присутстсвует более свежая версия, чем прописано в зависимостях манифеста, то будет использована именно она.

R>... в таком случае, зачем alexyv в своём журнале в записи Side-by-side assemblies и их проблемы приложение, состоящее из нескольких модулей, каждый из которых ссылается на разные версии CRT, конфигурирует с помощью <dll-name>.2.config файлов?


Представь ситуацию: на компьютере установлена некотороая shared сборка версии 1.1, а приложение собрано с использованием сборки версии 1.0, но без проблем может работать и с версией 1.1. Поиск версии 1.0 закончится неудачей и (без дополнительных действий) приложение не будет загружено, т.к. требуется полное совпадение версий (в том числе). С помощью *.config файла можно описать перенаправление зависимости от версии 1.0 к версии 1.1 (см. атрибут bindingRedirect).

В том случае, если ты являешся автором shared сборки, то такого же результата можно добиться с помощью рublisher сonfiguration file (*.policy).

R>Потому что использует private сборку, расположенную в одной с приложением директории, вместо public сборки, установленной в WinSxS?


Нет, разница между shared/private сборками ортогональна конфликтам версий.
Re: DLL-Связывание. Поиск DLL. Манифесты.
От: Rakafon Украина http://rakafon.blogspot.com/
Дата: 16.11.09 17:29
Оценка:
Кстати по поводу Side-by-Side assembly technology и месте в ней таких сборок, как CRT/MFC/ATL/etc.

Visual Studio 2010 Beta 2:

Besides the “bling”, notable changes include the Visual C++ 2010 CRT reverting to the traditional deployment model used by the Visual C++ 2003 CRT. More specifically, the CRT DLLs no longer use SxS binding (“Fusion”) and are now simply deployed to the “system32″ directory or to the application’s directory, as desired. Dropping SxS has some obvious disadvantages (SxS binding redirects would no longer be able to redirect applications that load a private copy of the CRT DLLs to updated versions with bug fixes and security updates) but presumably the pain of integrating SxS deployment into the setup process, which required either an MSI installation or pseudo-documented use of the SxS API, resulted in too much negative feedback and they chose to revert to the legacy approach.


... короче не будет больше Microsoft.VC90.ATL и Microsoft.VC90.CRT сборок, лежащих в C:\Windows\WinSxS директории, возвращаемся во временя DLL-Hell, теперь все эти DLL-ки снова будут находиться в C:\Windows\system32 ...

... я так понял народ, вместо того, чтобы разобраться, просто ниасилил SxS механизмы, стал линковаться статически с CRT и ATL и вкрай задолбал Microsoft багрепортами, вот они и откатились назад ...

"Дайте мне возможность выпускать и контролировать деньги в государстве и – мне нет дела до того, кто пишет его законы." (c) Мейер Ансельм Ротшильд , банкир.
redist
Re[2]: DLL-Связывание. Поиск DLL. Манифесты.
От: Kingofastellarwar Украина  
Дата: 17.11.09 16:28
Оценка:
Здравствуйте, Rakafon, Вы писали:

R>... я так понял народ, вместо того, чтобы разобраться, просто ниасилил SxS механизмы, стал линковаться статически с CRT и ATL и вкрай задолбал Microsoft багрепортами, вот они и откатились назад ...


Нифига подобного. Я достаточно намучался с этим, и оказалось что тот единственный нормальный подход(с приватными сборками) и он оказался полурабочим.
Потому что если у вас все бинарники свалены в одно папку в которой лежите и сам црт, то проблем нет, а вот если у вас есть модули/плагины в других папках,
то даже если задать правильный путь в манифестах в папку с црт то всё равно это не работало у меня на висте, а работало только на ХР.

Инсталяции я даже не рассматриваю, потому что инсталяция — это зло.
+ сами мёрж модули и отдельные дистрибы которые идут со студией, ставятся очень раздражающе: например если у вас уже стоит црт в SxS, то инсталятор будет минут 10 опредлять, что не нада ничего ставить — п****ц.
А метода определения что оно уже стоит — нет.

Кароче все стандартные подходы — ограниченные и/или кривые.

Поэтому если у вас есть подпаки с ДДЛками то я делаю так:
Сделайте папку Bin в котрой будет exe, crt, манифесты и прочее
Модули/Плагины перед LoadLibrary копируйте в Bin и оттуда грузите.
Заодно получите подобие hot-deploy
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Re[3]: DLL-Связывание. Поиск DLL. Манифесты.
От: Rakafon Украина http://rakafon.blogspot.com/
Дата: 17.11.09 17:17
Оценка:
Здравствуйте, Kingofastellarwar, Вы писали:
K>Сделайте папку Bin в котрой будет exe, crt, манифесты и прочее
K>Модули/Плагины перед LoadLibrary копируйте в Bin и оттуда грузите.
K>Заодно получите подобие hot-deploy :))

Круто! А где, собственно директория "Bin" должна жить? Не подскажете волшебное местечко в файловой системе? Т.е. я хочу сказать, что, например, в моём EXE приложении, "живёт" ActiveX, и приложение, к примеру, поднимается Internet Explorer'ом, отчего получает low integrity level на Висте, и соотвественно оно не то что в %PROGRAMMFILES%, оно даже в %APPDATA% ничего написать не сможет. Вот где от "hot-deploy" радости можно выгрести полные штаны!
:)
"Дайте мне возможность выпускать и контролировать деньги в государстве и – мне нет дела до того, кто пишет его законы." (c) Мейер Ансельм Ротшильд , банкир.
Re[4]: DLL-Связывание. Поиск DLL. Манифесты.
От: Kingofastellarwar Украина  
Дата: 17.11.09 17:21
Оценка:
Здравствуйте, Rakafon, Вы писали:

R>Здравствуйте, Kingofastellarwar, Вы писали:

K>>Сделайте папку Bin в котрой будет exe, crt, манифесты и прочее
K>>Модули/Плагины перед LoadLibrary копируйте в Bin и оттуда грузите.
K>>Заодно получите подобие hot-deploy

R>Круто! А где, собственно директория "Bin" должна жить? Не подскажете волшебное местечко в файловой системе? Т.е. я хочу сказать, что, например, в моём EXE приложении, "живёт" ActiveX, и приложение, к примеру, поднимается Internet Explorer'ом, отчего получает low integrity level на Висте, и соотвественно оно не то что в %PROGRAMMFILES%, оно даже в %APPDATA% ничего написать не сможет. Вот где от "hot-deploy" радости можно выгрести полные штаны!

R>

И что, даже в %ТМП% писать не может? Ну тогда прийдётся вам иметь весь букет SxS геморроя.
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Re[4]: DLL-Связывание. Поиск DLL. Манифесты.
От: Kingofastellarwar Украина  
Дата: 17.11.09 17:29
Оценка:
Здравствуйте, Rakafon, Вы писали:

R>Здравствуйте, Kingofastellarwar, Вы писали:

K>>Сделайте папку Bin в котрой будет exe, crt, манифесты и прочее
K>>Модули/Плагины перед LoadLibrary копируйте в Bin и оттуда грузите.
K>>Заодно получите подобие hot-deploy

R>Круто! А где, собственно директория "Bin" должна жить? Не подскажете волшебное местечко в файловой системе? Т.е. я хочу сказать, что, например, в моём EXE приложении, "живёт" ActiveX, и приложение, к примеру, поднимается Internet Explorer'ом, отчего получает low integrity level на Висте, и соотвественно оно не то что в %PROGRAMMFILES%, оно даже в %APPDATA% ничего написать не сможет. Вот где от "hot-deploy" радости можно выгрести полные штаны!

R>

Ну и к тому же если прога является тем, что интегрируется в систему, то ясное дело что тут инсталяция показана. Иначе это равносильно как пытаться сделать портабл сервис ))
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Re[5]: DLL-Связывание. Поиск DLL. Манифесты.
От: Rakafon Украина http://rakafon.blogspot.com/
Дата: 17.11.09 18:24
Оценка:
Здравствуйте, Kingofastellarwar, Вы писали:
K>Ну и к тому же если прога является тем, что интегрируется в систему, то ясное дело что тут инсталяция показана. Иначе это равносильно как пытаться сделать портабл сервис :)))))

Да не, у меня ничё нигде не интегрируется, просто обычное приложение, запускаемое либо из explorer.exe либо из svchost.exe (приложение является ещё и сервером COM объектов). Это я просто выдумываю ситуацию, чисто гипотетически. Потому как завтра мне вполне могут дать таск, в результате чего это всё придётся учитывать.

Сегодня я просто ставлю необходимые мне сборки используя merge модули. Однако упомянутая вами выше тормознутость msiexec.exe имеет место быть: заказчик мне прислал жалобу, что во время инсталляции софтины "On Vista, I observed that the installer left a dangling reference to "msiexec.exe". I had to kill it in task manager.", и произошло это именно во время установки этих merge модулей. А приватными эти сборки я также не могу сделать, ибо у меня приложение состоит из нескольких процессов, и эти процессы валяются по разным директориям. Я пока что, собственно, не приступил к поиску солюшена этой траблы: но на перспективу думаю найти способ установки в SxS кастомных shared сборок, и тогда положу туда CRT и ATL, и соответственно сносить их буду во время анинсталла.
"Дайте мне возможность выпускать и контролировать деньги в государстве и – мне нет дела до того, кто пишет его законы." (c) Мейер Ансельм Ротшильд , банкир.
Re[6]: DLL-Связывание. Поиск DLL. Манифесты.
От: Kingofastellarwar Украина  
Дата: 17.11.09 18:42
Оценка: 1 (1)
Здравствуйте, Rakafon, Вы писали:

R>Здравствуйте, Kingofastellarwar, Вы писали:

K>>Ну и к тому же если прога является тем, что интегрируется в систему, то ясное дело что тут инсталяция показана. Иначе это равносильно как пытаться сделать портабл сервис ))

R>Да не, у меня ничё нигде не интегрируется, просто обычное приложение, запускаемое либо из explorer.exe либо из svchost.exe (приложение является ещё и сервером COM объектов). Это я просто выдумываю ситуацию, чисто гипотетически. Потому как завтра мне вполне могут дать таск, в результате чего это всё придётся учитывать.


R>Сегодня я просто ставлю необходимые мне сборки используя merge модули. Однако упомянутая вами выше тормознутость msiexec.exe имеет место быть: заказчик мне прислал жалобу, что во время инсталляции софтины "On Vista, I observed that the installer left a dangling reference to "msiexec.exe". I had to kill it in task manager.", и произошло это именно во время установки этих merge модулей. А приватными эти сборки я также не могу сделать, ибо у меня приложение состоит из нескольких процессов, и эти процессы валяются по разным директориям. Я пока что, собственно, не приступил к поиску солюшена этой траблы: но на перспективу думаю найти способ установки в SxS кастомных shared сборок, и тогда положу туда CRT и ATL, и соответственно сносить их буду во время анинсталла.


Проблему отсутвия прав я тоже думал:
Если вы можете писать хотя б в %ТМП%, то можно сделать дополнительный ехе, который при запуске скопирует в TMP все бинарники всех процессов,
и запустит главный ехе передав ему как комманд лайн параметр путь к себе, чтобы он знал откуда был рождён.

У меня например в пылу борьбы с sxs гланый exe превратился в ничего не умеющий загрузчик, слинкованый статичесик и по минимому, который изначально предполагалось что будет определять чего не хватает для запуска сиситемы и самостоятельно устанавливать это беря из соотв папки.
Но красиво это сделать не получилось потому, что при ошибках в зависимостях при LoadLibrary винда мессадж боксы показывает, вместо того чтобы тихо ошибку вернуть.
Но на будущее я всё это оставил.
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Re[7]: DLL-Связывание. Поиск DLL. Манифесты.
От: Carc Россия https://vk.com/gosha_mazov
Дата: 17.11.09 20:55
Оценка:
K>Но красиво это сделать не получилось потому, что при ошибках в зависимостях при LoadLibrary винда мессадж боксы показывает, вместо того чтобы тихо ошибку вернуть.
K>Но на будущее я всё это оставил.
+1 тоже накушался этих MessageBox`ов — на кой это было надо делать Microsoft`у в толк никак не возьму. Стандартному самому обыкновенному юзеру от этих премудростей что "Not Found concrete.DLL" не тепло, не холодно. Нормальному "хомячку" это вообще мало что говорит, и вгоняет только лишний ступор, зато как клево это может ронять все подряд, слов нету Действительно, чем мешал старый подход с кодом ошибки — непонятно.

А как решили выкручиваться с поисками нужной ДЛЛ? Я без конца "жонглировал" SetCurrentDirectory, чтобы Windows увидела искомую DLL. Но это еще те танцы с бубнами, может есть какой способ покошернее?
Aml Pages Home
Re[8]: DLL-Связывание. Поиск DLL. Манифесты.
От: Kingofastellarwar Украина  
Дата: 17.11.09 21:26
Оценка:
Здравствуйте, Carc, Вы писали:

C>А как решили выкручиваться с поисками нужной ДЛЛ? Я без конца "жонглировал" SetCurrentDirectory, чтобы Windows увидела искомую DLL. Но это еще те танцы с бубнами, может есть какой способ покошернее?


Т.е.? Как ссылаемся на CRT ДЛЛки?
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Re[9]: DLL-Связывание. Поиск DLL. Манифесты.
От: Carc Россия https://vk.com/gosha_mazov
Дата: 17.11.09 22:17
Оценка:
Здравствуйте, Kingofastellarwar, Вы писали:

K>Здравствуйте, Carc, Вы писали:


C>>А как решили выкручиваться с поисками нужной ДЛЛ? Я без конца "жонглировал" SetCurrentDirectory, чтобы Windows увидела искомую DLL. Но это еще те танцы с бубнами, может есть какой способ покошернее?


K>Т.е.? Как ссылаемся на CRT ДЛЛки?

Та не! Я вообще о вопросе поиска нужной ДЛЛ.
У меня была проблема НЕ с CRT, а с реализациями RichEdit разных версий... (млин, эти ДЛЛ еще и одноименные через версию ).
Тут-то собсна все и началось: если в двух словах, то нужный RichEdit в общем случае было известно где искать, и как правило он там есть. Но он цепляет еще одну DLL, причем похоже откуда-то из своей собственной DllMain — то бишь еще до малейшей попытки хоть что-то поюзать из загруженной DLL, пыталась грузиться эта самая дополнительная DLL...

Вот тут все и началось: если в псевдокоде, то что-то подобного вида
Шаг 1) находим полный путь к нужной версии с RichEdit.DLL
Шаг 2) ставим новую текущую папку SetCurrentDirectory(папка_с_той_самой_дополнительной_длл) (ее тоже примерно известно где искать)
Шаг 3) Грузим RichEdit.DLL из п.1 указавая полный путь (дабы не баловала с другими версиями одноименной RichEdit.DLL).
Шаг 4) При загрузке RichEdit.DLL в п.3, т.к. мы уже выставили SetCurrentDirectory в п.2. — то по этому пути и искалась эта самая дополнительная ДЛЛ, ну и успешно загружалась.
Шаг 5) Возвращаем предыдущий SetCurrentDirectory из п.2.

В противном случае, если выкинуть эти бубны, на загрузке RichEdit.DLL вылетал MessageBox — мол не нашла еще одну ДЛЛ (причем этот MessageBox вообще ни к селу не к городу был, вплоть до Access Violation)

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

Вот от такого дремучего кода и хотелось бы избавиться!
Посматривал в сторону всяких SearchPath, но руки так и не дошли. Собсна отсюда и вопрос: а туда ли я полез? И нету ли способа попроще, а то так и хочется исходник переименовать в "Ничего_Не_Трогайте_НИКОГДА.h"
Aml Pages Home
Re[10]: DLL-Связывание. Поиск DLL. Манифесты.
От: Kingofastellarwar Украина  
Дата: 17.11.09 22:54
Оценка:
Здравствуйте, Carc, Вы писали:

K>>Здравствуйте, Carc, Вы писали:


Ааа не, такой проблемы не было.
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Re[10]: DLL-Связывание. Поиск DLL. Манифесты.
От: Rakafon Украина http://rakafon.blogspot.com/
Дата: 18.11.09 10:49
Оценка:
Здравствуйте, Carc, Вы писали:
C>Посматривал в сторону всяких SearchPath, но руки так и не дошли. Собсна отсюда и вопрос: а туда ли я полез? И нету ли способа попроще, а то так и хочется исходник переименовать в "Ничего_Не_Трогайте_НИКОГДА.h" :(

Мне как-то тоже было необходимо внести свои корректировки в процесс поиска нужной DLL. Но Current Directory я не трогал. ИМХО, муторно это туда сюда гонять эту директорию: то она здесь, то она там, то опять здесь, так легко и провтыкать где-то в коде ненароком и отловить нехилую бажину. Я вместо этого изменял переменную окружения PATH для своего процесса.

Ну допустим, требуемая DLL валяется по следующему пути "С:\Program Files\Dazdraperma\ProletariiVsehStranSoyedinyaytes.DLL", и директория в системной PATH не имеется, и эта директория не является текущей директорией процесса. Я делал примерно так:


// Initialize PATH environment variable for current process

typedef std::basic_string<TCHAR, std::char_traits<TCHAR>, std::allocator<TCHAR> > String_t;
typedef boost::scoped_array<TCHAR> TCharBuff_t;

String_t addDirPath = "С:\\Program Files\\Dazdraperma";

DWORD pathBufferSize = ::GetEnvironmentVariable(_T("PATH"), NULL, 0L);
pathBufferSize += addDirPath.length() + 3;

TCharBuff_t pathBuffer(new TCHAR[pathBufferSize]);
ZeroMemory(pathBuffer.get(), pathBufferSize * sizeof(TCHAR));

DWORD getEnvRet = ::GetEnvironmentVariable(_T("PATH"), pathBuffer.get(), pathBufferSize);

if ( getEnvRet )
{
    _tcscat(pathBuffer.get(), _T(";"));
    _tcscat(pathBuffer.get(), addDirPath.c_str());
    _tcscat(pathBuffer.get(), _T(";"));

    BOOL setEnvRet = ::SetEnvironmentVariable(_T("PATH"), pathBuffer.get());

    if ( NULL == setEnvRet )
    {
        // write Win 32 API error to LOG
    }
}
else
{
    // write Win 32 API error to LOG
}


Таким образом можно однажды при запуске апликухи добавить нужную директорию (или все интересующие директории) в переменную окружения PATH, а дальше по коду просто вызывать LoadLibrary(_T("ProletariiVsehStranSoyedinyaytes.DLL")) (или вызывать LoadLibrary для всех интересующих модулей, раскиданных по всяким папкам) и всё работает, и не надо туда сюда переписывать Current Directory.
"Дайте мне возможность выпускать и контролировать деньги в государстве и – мне нет дела до того, кто пишет его законы." (c) Мейер Ансельм Ротшильд , банкир.
assembly dll dllhell getenvironmentvariable setenvironmentvariable
Re[7]: DLL-Связывание. Поиск DLL. Манифесты.
От: Rakafon Украина http://rakafon.blogspot.com/
Дата: 18.11.09 11:28
Оценка:
Здравствуйте, Kingofastellarwar, Вы писали:
K>Но красиво это сделать не получилось потому, что при ошибках в зависимостях при LoadLibrary винда мессадж боксы показывает, вместо того чтобы тихо ошибку вернуть.
K>Но на будущее я всё это оставил.

Кстати MessageBox'овая болячка банально может быть вылечена перехватом Win32 API вызовов по методу описанному в книге Рихтера. Перехватив вызов всех возможных MessageBox'овых функций, можно не редиректить на вызов оригинальных функций, а просто забить на этот мессадж и ничего не показывать.
"Дайте мне возможность выпускать и контролировать деньги в государстве и – мне нет дела до того, кто пишет его законы." (c) Мейер Ансельм Ротшильд , банкир.
Re[11]: DLL-Связывание. Поиск DLL. Манифесты.
От: Carc Россия https://vk.com/gosha_mazov
Дата: 19.11.09 02:19
Оценка:
Здравствуйте, Rakafon, Вы писали:

R>Здравствуйте, Carc, Вы писали:

C>>Посматривал в сторону всяких SearchPath, но руки так и не дошли. Собсна отсюда и вопрос: а туда ли я полез? И нету ли способа попроще, а то так и хочется исходник переименовать в "Ничего_Не_Трогайте_НИКОГДА.h"

R>Мне как-то тоже было необходимо внести свои корректировки в процесс поиска нужной DLL. Но Current Directory я не трогал. ИМХО, муторно это туда сюда гонять эту директорию: то она здесь, то она там, то опять здесь, так легко и провтыкать где-то в коде ненароком и отловить нехилую бажину. Я вместо этого изменял переменную окружения PATH для своего процесса.


R>Ну допустим, требуемая DLL валяется по следующему пути "С:\Program Files\Dazdraperma\ProletariiVsehStranSoyedinyaytes.DLL", и директория в системной PATH не имеется, и эта директория не является текущей директорией процесса. Я делал примерно так:



R>
R>// Initialize PATH environment variable for current process

R>typedef std::basic_string<TCHAR, std::char_traits<TCHAR>, std::allocator<TCHAR> > String_t;
R>typedef boost::scoped_array<TCHAR> TCharBuff_t;

R>String_t addDirPath = "С:\\Program Files\\Dazdraperma";

R>DWORD pathBufferSize = ::GetEnvironmentVariable(_T("PATH"), NULL, 0L);
R>pathBufferSize += addDirPath.length() + 3;

R>TCharBuff_t pathBuffer(new TCHAR[pathBufferSize]);
R>ZeroMemory(pathBuffer.get(), pathBufferSize * sizeof(TCHAR));

R>DWORD getEnvRet = ::GetEnvironmentVariable(_T("PATH"), pathBuffer.get(), pathBufferSize);

R>if ( getEnvRet )
R>{
R>    _tcscat(pathBuffer.get(), _T(";"));
R>    _tcscat(pathBuffer.get(), addDirPath.c_str());
R>    _tcscat(pathBuffer.get(), _T(";"));

R>    BOOL setEnvRet = ::SetEnvironmentVariable(_T("PATH"), pathBuffer.get());

R>    if ( NULL == setEnvRet )
R>    {
R>        // write Win 32 API error to LOG
R>    }
R>}
R>else
R>{
R>    // write Win 32 API error to LOG
R>}
R>


R>Таким образом можно однажды при запуске апликухи добавить нужную директорию (или все интересующие директории) в переменную окружения PATH, а дальше по коду просто вызывать LoadLibrary(_T("ProletariiVsehStranSoyedinyaytes.DLL")) (или вызывать LoadLibrary для всех интересующих модулей, раскиданных по всяким папкам) и всё работает, и не надо туда сюда переписывать Current Directory.


Не-е-е! Не катит! Уж больно глобальное решение — влияет на все в пределах процесса, чем такое может кончиться боязно и подумать
1) В MSDN сказано что PATH проверяется последней когда ищется DLL, то бишь в моем случае как нефиг делать может загрузиться искомая DLL из других путей (%SYSDIR%, %WINDIR% и.т.д.) ибо найдется раньше — а библиотечка вполне с одноименным и распространенным названием (RichEd20.DLL — часть PSDK, причем имя файла DLL одно и тоже, а версий компонентов там как минимум 3 точно может быть — а это было важно по сути задачи).

2) Установка PATH да к тому же для всего процесса влияет на поиск всех грузящихся ДЛЛ — чем это закончится для соседнего кода неизвестно — ну ее в болоту это глобализацию...

3) Если поставить еще одну директорию в PATH, то одному господу богу, где, и как, и кто может загрузиться за компанию. В моем случае искомая библиотека была в недрах Common Files\Microsoft Shared. Если я этот путь положу в PATH, то что оттуда и еще какое-нить мс-офисное барахло подгрузится стремно и подумать... А вот MS-офисных расширений, не пойми чем занимающихся в моем адресном пространстве точно не нужно — и так хваленой Windows-ской совместимости с головой хватает Это как некая конкретизация п.2

4) Трабла с SetCurrentDirectory была мрачно автоматизирована в стиле идиомы "владелец ресурса"
нечто вроде
class CAutoDirectory {
CString m_strPrevDir;
operator new();//new - в private его батеньку, в private чтобы никто и никогда и ни при каких! 
public:
//конструктор изменяет текущую директорию
//и запоминает предыдущую
CAutoDirectory(CString strNewDir)
{
GetCurrentDirectory(m_strPrevDir);
SetCurrentDirectory(strNewDir);
}
//деструктор ставит обратно предыдущую директорию
~CAutoDirectory()
{
SetCurrentDirectory(m_strPrevDir);
};

//ну и в коде понеслось
//объявляем на стеке, деструктор сам все вернет на круги своя
CAutoDirectory directory_owner(strNewDir);


Ну это так, класс навскидку написан, как иллюстрация — в реальном коде конечно же и проверки всякие были, и прочая муть чтобы лишней работы не делать. В таком варианте всеми траблами мается сам компилятор, об этом заботиться уже не приходиться.
Aml Pages Home
Re[8]: DLL-Связывание. Поиск DLL. Манифесты.
От: Carc Россия https://vk.com/gosha_mazov
Дата: 19.11.09 02:24
Оценка: 1 (1)
Здравствуйте, Rakafon, Вы писали:

R>Здравствуйте, Kingofastellarwar, Вы писали:

K>>Но красиво это сделать не получилось потому, что при ошибках в зависимостях при LoadLibrary винда мессадж боксы показывает, вместо того чтобы тихо ошибку вернуть.
K>>Но на будущее я всё это оставил.

R>Кстати MessageBox'овая болячка банально может быть вылечена перехватом Win32 API вызовов по методу описанному в книге Рихтера. Перехватив вызов всех возможных MessageBox'овых функций, можно не редиректить на вызов оригинальных функций, а просто забить на этот мессадж и ничего не показывать.

1. можно поюзать функцию SetErrorMode!
2. Или уж не проще ли тогда хук поставить причем именно на поток, который грузит ДЛЛ? И не мудрить с перехватом, зачем недокументированное что-то юзать?
Aml Pages Home
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.