Страницы: 1
.. а точнее, проблема доступа к ним. Ситуация: имеется самописная сишная dll, платформа - WINNTx86/MSVC. Пытаюсь сделать простейший вызов с использованием ctypes.jsm - нативный метод без входных параметров просто возвращает версию dll. Для начала кладу dll в %SystemRoot%\system32. Вызов отрабатывает нормально, всё в порядке. Далее, в соответствии с изложенными здесь рекомендациями, пытаюсь поместить библиотеку в папку components расширения. В манифесте указываю:
binary-component components/foolib.dll ABI=WINNT_x86-msvc
с сообщением "can't open library". Вставляю в код
- возвращает "foolib.dll", пытаюсь результат от ctypes.libraryName("foolib") вставить в ctypes.open - та же ошибка. Всяческие манипуляции с путем, именем, и т.п. результата не дали. В результате я поступил так: положил dll в modules, рядом с jsm, который эту библиотеку использует, путь к dll получаю так:
AddonManager.getAddonByID(extID, function(addon) { var lib = addon.getResourceURI("modules/foolib.dll").QueryInterface(Ci.nsIFileURL).file; libpath=lib.exists() ? lib.path : null; });
- этот код работает вполне нормально. Но всё же остается открытым вопрос, как использовать библиотеку в случае, если она входит в состав xpi - а такой случай предусмотрен, и вполне может считаться штатным. Ведь вышеприведенное объявление в манифесте, например, позволяет контролировать целевую платформу - иначе придется делать это своими кустарными методами (через nsIXULRuntime/nsIXULAppInfo). Ну, и вообще хотелось бы в итоге сделать "как положено", а не опять же своими кустарными способами.
Отсутствует
Возвращаясь к теме: в Nightly Tester Tools недавно случайно наткнулся, как вопрос с бинарным компонентом решают они. Выглядит это так: в chrome.manifest прописывается
binary-component platform/WINNT_x86-msvc/foolib.dll ABI=WINNT_x86-msvc
var dir = __LOCATION__.parent.parent; var file = dir.clone(); file.append("platform"); let xr = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime); file.append(xr.OS + "_" + xr.XPCOMABI); file.append(ctypes.libraryName("foolib")); var libpath=file.path;
т.е. всё же получается, что каких-то встроенных функций, базирующихся на информации из chrome.manifest для бинарного компонента, нет, и путь к компоненту конструируется фактически вручную - я его мог бы положить в папку с любым именем, а дальше, отталкиваясь от __LOCATION__, сконструировать путь. Но лучше всё же уж так, чем определять путь в коллбэке AddonManager.getAddonByID...
Отсутствует
Кажется, относительно прописывания бинарных компонентов в chrome.manifest всё прояснилось. Строка вида
binary-component platform/WINNT_x86-msvc/foolib.dll ABI=WINNT_x86-msvc
interfaces components/fooClass.xpt
binary-component platform/WINNT_x86-msvc/foolib.dll ABI=WINNT_x86-msvc
Теперь вопрос следующий. Он находится немного в стороне от данной темы, но связан с ней. Бинарный компонент при старте FF вешает хук на главное окно FF, метод коллбэка хука - в той же dll, которая объявлена для компонента в манифесте. Разумеется, после навешивания хука на dll вешается блокировка файловой системы. Сама логика работы расширения не предполагает снятия хука (хотя метод для этого на всякий случай предусмотрен). Но: при удалении расширения хук необходимо снять, иначе расширение не удалится ввиду наличия блокировки на dll. Напрашивается решение в виде некоего uninstall-скрипта, который будет подчищать перед удалением всё, что нельзя удалить штатными средствами. Только лично я расширений с функционалом в виде uninstall не видел - поэтому если кому-то такие известны - сообщите, пожалуйста.
Отсутствует
расширений с функционалом в виде uninstall
https://developer.mozilla.org/en/Addons … ener%28%29
https://developer.mozilla.org/en/Observ … on_Manager
Я пробовал примерно так:
extensionUninstaller = { guid: "some@guid", isUninstall: false, uninstallConfirmed: false, get oSvc() { delete this.oSvc; return this.oSvc = Components.classes["@mozilla.org/observer-service;1"] .getService(Components.interfaces.nsIObserverService); }, get newAddonManager() { delete this.newAddonManager; return this.newAddonManager = !("@mozilla.org/extensions/manager;1" in Components.classes); }, initUninstallObserver: function() { this.oSvc.addObserver(this, "quit-application-granted", false); if(this.newAddonManager) { try { // In Gecko 2 XPCOM can starts after "final-ui-startup" this.addAddonListener(); } catch(e) { // Wait for AddonManager startup this.oSvc.addObserver(this, "final-ui-startup", false); } } else this.oSvc.addObserver(this, "em-action-requested", false); }, destroyUninstallObserver: function() { this.oSvc.removeObserver(this, "quit-application-granted"); if(this.newAddonManager) AddonManager.removeAddonListener(this); else this.oSvc.removeObserver(this, "em-action-requested"); }, observe: function(subject, topic, data) { if(topic == "final-ui-startup") { this.oSvc.removeObserver(this, "final-ui-startup"); this.addAddonListener(); } else if(topic == "quit-application-granted") { this.destroyUninstallObserver(); if(this.isUninstall && this.uninstallConfirmed) this.uninstall(); } else if( topic == "em-action-requested" && subject instanceof Components.interfaces.nsIUpdateItem && subject.id == this.guid ) { if(data == "item-uninstalled") this.handleUninstalling(); else if(data == "item-cancel-action") this.isUninstall = false; } }, addAddonListener: function() { // Firefox 3.7a5pre+: // In Firefox 1.5 we can't use "import" keyword (we get syntax error) Components.utils["import"]("resource://gre/modules/AddonManager.jsm"); //AddonManagerPrivate.startup(); AddonManager.addAddonListener(this); }, onUninstalling: function(ext, requiresRestart) { if(ext.id == this.guid) this.handleUninstalling(); }, onOperationCancelled: function(ext) { if( ext.id == this.guid && !(ext.pendingOperations & AddonManager.PENDING_UNINSTALL) ) this.isUninstall = false; }, handleUninstalling: function() { this.isUninstall = true; this.uninstallConfirm(); }, uninstallConfirm: function() { this.uninstallConfirmed = true; // Or ask user... }, uninstall: function() { // Do something } }; extensionUninstaller.initUninstallObserver();
(Основано на коде Mouse Gestures и чего-то еще – забыл, давно дело было )
Правда, проверялось все это когда новый AddonManager еще только появился. Пока работает, вроде бы.
Прошлое – это локомотив, который тянет за собой будущее. Бывает, что это прошлое вдобавок чужое. Ты едешь спиной вперед и видишь только то, что уже исчезло. А чтобы сойти с поезда, нужен билет. Ты держишь его в руках. Но кому ты его предъявишь?
Виктор Пелевин. Желтая стрела
Отсутствует
Infocatcher
Спасибо, буду пробовать.
Отсутствует
Infocatcher
Всё, сделал свой uninstaller - всё практически как в приведенном вами коде. Единственное, с чем пришлось немного повозиться - вот с этим моментом:
try { // In Gecko 2 XPCOM can starts after "final-ui-startup" this.addAddonListener(); } catch(e) { // Wait for AddonManager startup this.oSvc.addObserver(this, "final-ui-startup", false); }
- хотя у меня, сколько раз я ни пробовал, XPCOM стартовал всегда до final-ui-startup, я решил просто смоделировать ситуацию - топик не ловился. Выяснилось, что для того, чтобы поймать final-ui-startup, нужен обсервер, зарегистрированный через Category Manager на profile-after-change, тогда все прочие подписчики смогут поймать в т.ч. и final-ui-startup - в Mouse Gestures именно так и сделано. А в остальном всё работает вполне нормально. Спасибо.
Отсутствует
Подниму тему, т.к. ниже речь пойдет о проблеме, связанной именно с бинарным компонентом в расширении (вот в этом). Итак, пользователь сообщает, что у него расширение не работает. У меня, и еще у энного количества пользователей оно работает нормально (проверялось для WinXP/Vista/Win7). Начинаю разбираться - выясняется, что первое же обращение через ctypes к методу в dll возвращает ошибку с кодом 998 - это то, что возвращает WinAPI-функция GetLastError. 998 - это ERROR_NOACCESS, возвращаемый LoadLibrary. Далее, выясняется, что у пользователя Win7 x64 (а официальных сборок x64 для FF4.x в природе не существует; есть только ночные англоязычные). Следовательно, с очень большой вероятностью FF, несмотря на х64-ОС, 32-х битный. Бинарный компонент компилировался под x86 target platform (со статической линковкой). И несмотря на то, что в chrome.manifest абсолютно однозначно указано, что
binary-component platform/WINNT_x86-msvc/skl.dll ABI=WINNT_x86
-msvc
alert(Components.classes["@mozilla.org/xre/app-info;1"] .getService(Components.interfaces.nsIXULRuntime).XPCOMABI);
(если что - под спойлером код для кастомной кнопки)
custombutton://%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0D%0A%3Ccustombutton%20xmlns%3Acb%3D%22http%3A//xsms.nm.ru/custombuttons/%22%3E%0A%20%20%3Cname%3ECheckOSABI%3C/name%3E%0A%20%20%3Cimage%3E%3C%21%5BCDATA%5Bcustombuttons-stdicon-1%5D%5D%3E%3C/image%3E%0A%20%20%3Cmode%3E0%3C/mode%3E%0A%20%20%3Cinitcode%3E%3C%21%5BCDATA%5B/*Initialization%20Code*/%5D%5D%3E%3C/initcode%3E%0A%20%20%3Ccode%3E%3C%21%5BCDATA%5Balert%28Components.classes%5B%22@mozilla.org/xre/app-info%3B1%22%5D%0A%20%20%20%20.getService%28Components.interfaces.nsIXULRuntime%29.XPCOMABI%29%3B%0A%5D%5D%3E%3C/code%3E%0A%20%20%3Caccelkey%3E%3C%21%5BCDATA%5B%5D%5D%3E%3C/accelkey%3E%0A%20%20%3Chelp%3E%3C%21%5BCDATA%5B%5D%5D%3E%3C/help%3E%0A%20%20%3Cattributes/%3E%0A%3C/custombutton%3E
Отредактировано hydrolizer (11-09-2012 03:42:54)
Отсутствует
Но это потом, сейчас просто хотелось бы выдавать сообщение о невозможности работы на 64-х разрядной платформе - а для этого надо как-то определить фактическую разрядность платформы.
Разве нельзя ли из расширения определить текущий user agent браузера?
Присутствие там WOW64 сразу говорит о том что это 32-битный браузер запущенный на 64-битной ОС.
Do not meddle in the affairs of Wizards, for they are subtle and quick to anger.
Отсутствует
Unghost
Да, user agent вполне можно определить. Мне как раз не хватало подсказки в этом направлении. Спасибо.
Отсутствует
Страницы: 1