Короткая версия : каким образом элемент управления MFC ActiveX, загружаемый на веб-страницу Internet Explorer, гарантирует, что связанные с ним библиотеки DLL загружаются из своего собственного каталога, а не выбирает библиотеки с одинаковыми именами, которые уже могут быть загружен в процесс?
Длинная версия, с кровавыми подробностями : У меня есть приложение myapp.exe
, которое использует набор DLL: one.dll
, two.dll
и three.dll
.
Те же библиотеки DLL также используются элементом управления MFC ActiveX, который предоставляет некоторые из тех же функций, что и myapp.exe
, поэтому есть mycontrol.ocx
, который также связывается с этими библиотеками DLL. Элемент управления ActiveX связан с типом application/myapp
MIME, поэтому IE будет использовать его для отображения документов, созданных с помощью myapp.exe
.
Возможно установить обе версии 1 и 2 myapp.exe
, но только самая последняя версия mycontrol.ocx
(версия 2) связана с типом application/myapp
MIME:
c:\Program Files\MyApp\Version 1\
myapp.exe
mycontrol.ocx
one.dll
two.dll
three.dll
c:\Program Files\MyApp\Version 2\
myapp.exe
mycontrol.ocx <-- registered with the MIME type
one.dll
two.dll
three.dll
Вот где это сложно: myapp.exe
имеет встроенный элемент управления Internet Explorer для отображения веб-контента. Вы можете запустить версию 1 myapp.exe
, указав, что встроенный Internet Explorer на документ application/myapp
, и IE загрузит версию 2 mycontrol.ocx
, чтобы просмотреть его. Это должно быть хорошо, но это не так:
В результате Windows загружает mycontrol.ocx
, видит, что она зависит от one.dll
и что в процессе уже есть one.dll
, и указывает таблицу импорта mycontrol.ocx
на уже загруженную ( версия 1) one.dll
, а не загрузка версии 2 из one.dll
. Это терпит неудачу, потому что версия 2 mycontrol.ocx
использует новые API в версии 2 one.dll
, которых не было в версии 1.
Как мне прекратить это делать? Если one.dll
еще не загружен, Windows будет искать его в c:\Program Files\MyApp\Version 2
, и все будет хорошо. (И я не могу переименовать все свои модули для каждой версии программного обеспечения!)
Неудачное решение # 1 : я дал mycontrol.ocx
манифест, который задает <file ...>
элементов для всех библиотек DLL, но это не работает. one.dll
загружается из каталога Version 2
, а two.dll
- нет. Я предполагаю, что это потому, что two.dll
загружается в результате one.dll
ссылки на него, а one.dll
не имеет такого манифеста.
Неудачное решение # 2 : Итак, я добавил манифест к всем библиотекам DLL, каждая из которых перечисляет свои зависимости в <file ...>
элементах. Но это полностью сломало myapp.exe
, потому что MFC теперь обрабатывает каждую DLL как имеющую собственный контекст активации, и это неправильно - должен быть один контекст MFC для всего процесса (в случае myapp.exe
) или всего экземпляра контроль (в случае mycontrol.exe
). У меня не может быть нового контекста активации для каждого модуля; Мне нужен один для всего mycontrol.ocx
и связанных с ним DLL.
Я изменил все манифесты, чтобы использовать один и тот же атрибут name=
, в надежде, что это поместит их всех в один и тот же контекст, но это никак не отразилось.
Неудачное решение # 3 : Я дал myapp.exe
манифест с надписью <file name="mycontrol.ocx"/>
в надежде заставить версию 1 приложения использовать версию 1 элемента управления, что было бы хорошо. Но это не удается, потому что когда Internet Explorer загружает mycontrol.ocx
, он вызывает LoadLibrary
с полным путем к версии 2 mycontrol.ocx
, и перенаправление манифеста не работает, когда модули загружаются с использованием полного пути.
Что-то, что я не могу сделать : Я не могу изменить код, который загружает элемент управления, потому что это делает Internet Explorer (через тип MIME).
Любые решения, предложения или простые сообщения сочувствия будут с благодарностью приняты.