Есть ли способ заставить IE выгрузить элемент управления ActiveX? - PullRequest
15 голосов
/ 06 марта 2009

У нас есть несколько динамических HTML-страниц, которые содержат тег <OBJECT>, который создает элемент управления ActiveX. Затем пользователь может перейти на другую страницу, которая содержит тег <OBJECT>, указывающий на более новую версию элемента управления ActiveX.

IE загрузит и установит новый ActiveX на второй странице, для чего и предназначена эта страница. Проблема заключается в том, что, поскольку IE загрузил ActiveX на первой странице, теперь он заставит пользователя перезагрузиться, прежде чем он полностью установит загруженный ActiveX, поскольку он используется процессом (IE).

В обычном контейнере я просто выгрузил бы ActiveX перед попыткой обновления. Есть ли способ заставить IE сделать это? Переход на страницу, которая не использует элемент управления, будет приемлемым, если это поможет.

Edit:

Решения, которые требуют, чтобы сам ActiveX что-то делал, не будут работать просто потому, что проблема в том, что ActiveX все еще находится в памяти, когда IE начинает установку новой версии ActiveX. То, что я пытаюсь сделать, это НЕ иметь ActiveX в памяти, когда IE запускает этот процесс, поэтому, очевидно, я не могу полагаться ни на что в самом элементе управления ActiveX.

Ответы [ 8 ]

7 голосов
/ 22 марта 2009

Попробуйте оператор удаления JavaScript:

function unloadObject(objId) {

    var obj = document.getElementById(objId);

    obj.parentNode.removeChild(obj);

    delete obj;
}

Позвоните unloadObject(targetActiveXTagId) перед тем, как открыть вторую страницу.

В идеале вы должны встроить механизм обновления в сам ActiveX. Я видел несколько платформ онлайн-игр, которые делают это с хорошими результатами.

2 голосов
/ 04 января 2010

Хотя я не знаю, как заставить IE выгружать DLL (он сохраняет дескриптор файла DLL открытым - надеюсь, он правильно высвобождает объекты ...), одно из решений, которое я использую, - это скопировать DLL поверх во временный файл (в зависимости от версии сборки), прежде чем открывать его, а затем явно нарушать кеширование IE / COM / что угодно. Таким образом, я могу загрузить «новую» версию, даже если старые файловые дескрипторы DLL остаются открытыми.

Я смог прервать кеширование только тогда, когда все из них выполнены:

  1. Другой ProgID (генерируется динамически, может отличаться от DLL)
  2. Другой CLSID (также динамически генерируется - работает как брелок)
  3. Другое имя DLL (создавая копию файла orig. И используя версию сборки, это позволяет избежать ошибок DLL-in-use-access)
  4. Другая версия сборки (это для .NET)

Я занимаюсь разработкой гаджета для боковой панели, поэтому я могу выполнить вышеизложенное только с некоторыми привилегированными компонентами ActiveX, дружественными к сценариям, но компонент ActiveX с предварительным загрузчиком (не обновленный) может также выполнить эту работу.

Я полагаюсь на .NET / mscoree.dll для обработки COM-содержимого, поэтому может быть более чистый метод перехода на более низкий уровень.

Различные "версии" обрабатываются с временными нагрузками в структуре HKCU \ Software \ Classes.

1 голос
/ 18 марта 2009

Я думаю, что это невозможно.

0 голосов
/ 21 марта 2009

Не можете ли вы изменить рабочий процесс? Сначала проверьте наличие обновлений и избегайте всей проблемы!

Какое бы решение вы ни внедрили, браузер контролируется клиентом, и любые обновления (безопасности) или новые версии могут сломать вашу систему.

0 голосов
/ 20 марта 2009

Вы пытались использовать Javascript для уничтожения элемента DOM, в котором живет ваш элемент управления ActiveX? Если вы сделаете это, IE сообщит элементу управления о необходимости выгрузки, но вы должны убедиться, что элемент управления действительно будет выгружен. Затем вы сможете попасть на страницу с новой ссылкой на объект, которая запустит новый объект ....

В противном случае вы можете попробовать открыть всплывающее окно, которое направляет вас на страницу, которая никогда не загружает ваш объект, и в то же время, используя именованную ссылку на главный браузер, перенаправить его на страницу, которая не ссылается на ваш объект, давая ему возможность выгрузить, а затем сделать повторную ссылку на ваш обновленный ActiveX. Это должно загрузить ваш новый элемент управления.

Это непростая проблема, независимо от того, в какую сторону вы идете, но вы можете заставить ее делать то, что вы хотите.

Если ваш элемент управления не работает должным образом, он может не выгружаться должным образом, поэтому вы должны следить за этим.

Larry

0 голосов
/ 19 марта 2009

Видимо да и нет.

Это может произойти, но только если вы «взломаете» его через уязвимость безопасности. Так что не через какой-либо законный процесс, нет.

Вот статья, описывающая состояние уязвимости: http://www.juniper.net/security/auto/vulnerabilities/vuln16409.html

А вот статья в Technet, в которой обсуждается, как DWORD ActiveX убивает процесс http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q240797&sd=tech

Это цитата с сайта MSDN об элементах управления ActiveX:

«Пользователи не могут напрямую взаимодействовать с элементами управления Microsoft ActiveX, загруженными элементами APPLET, EMBED или OBJECT. Пользователи могут взаимодействовать с такими элементами управления после активации своих пользовательских интерфейсов». http://msdn.microsoft.com/en-us/library/ms537508.aspx

0 голосов
/ 19 марта 2009

Одна вещь, которую вы можете попробовать, - это вызвать установщик CoFreeUnusedLibraries () , а затем ответить S_OK в DllCanUnloadNow () в элементе управления ActiveX. Это может выгрузить вас, хотя мне интересно, может ли IE попытаться перезвонить в ваш выгруженный модуль? Достаточно просто попробовать.

Вы также можете просто написать заглушку DLL, которая реализует все имеющиеся у вас интерфейсы, которые касаются IE, а затем просто передать вашу настоящую DLL, которая фактически реализует эту функциональность. Затем ваш установщик может передать сообщение «выгрузите настоящую DLL». Когда вы закончите, вы передадите другое сообщение, и оно загрузит новое. Пока происходит обновление, ваша заглушка выводит сообщение «Пожалуйста, подождите, пока я обновлю ...».

0 голосов
/ 17 марта 2009

Глупый ответ, извините. Я предполагаю, что перенаправление не сработало, если у вас все еще есть этот вопрос открытым. Если вы этого не делали, просто создайте страницу, которая перенаправляет на обновленную страницу ActiveX, и вместо этого создайте ссылку.

middleman.html:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>blank page</title>
<meta http-equiv="REFRESH" content="0;url=http://www.newactivexcontrol.com"></HEAD>
<BODY>
</BODY>
</HTML>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...