Не удалось открыть библиотеку (ошибка 126) с помощью ctypes.open в надстройке Firefox.

Разработка надстройки Firefox с использованием ctypes для загрузки пользовательской DLL. На моем реальном компьютере (win 7/64) DLL загружается без заминок, но внутри моей тестовой виртуальной машины с той же ОС возникает следующая ошибка:

console.error: bzaddon:
  Message: Error: couldn't open library .\BZAddOnHelper.dll: error 126
  Stack:
    @resource://bzaddon/index.js:25:11
run@resource://gre/modules/commonjs/sdk/addon/runner.js:145:19
startup/</<@resource://gre/modules/commonjs/sdk/addon/runner.js:86:7
Handler.prototype.process@resource://gre/modules/Promise-backend.js:867:23
this.PromiseWalker.walkerLoop@resource://gre/modules/Promise-backend.js:746:7
this.PromiseWalker.scheduleWalkerLoop/<@resource://gre/modules/Promise-backend.j
s:688:37

Код для загрузки библиотеки:

// Get the chrome components
let { Ci, Cu, Cr } = require('chrome');
// Get ctypes
Cu.import("resource://gre/modules/ctypes.jsm");
// External DLL
var lib = ctypes.open(".\\BZAddonHelper.dll");

Я даже пробовал с совершенно пустой DLL, которая НЕ зависит от msvc*:

скриншот "зависит" от целевой виртуальной машины

Я попытался переместить DLL в каталог данных и использовать self.data.url и вообще не использовать путь. Я пытался использовать полный путь. ЕДИНСТВЕННАЯ вещь, которая работает, - это копирование моей DLL в SysWow64 (DLL 32-битная, как 32-битная Firefox). Опять же, запуск этого на МОЕЙ машине (dev) работает с ".\dllname" - но не на любом другом компьютере... Я в полной и полной растерянности... Кто-нибудь?


person Uriel G    schedule 20.10.2015    source источник
comment
Обновление: получил тот же результат на виртуальной машине под управлением Windows 7/32....   -  person Uriel G    schedule 20.10.2015
comment
Обновление 2: получил тот же результат, скопировав kernel32.dll из C:\windows\system32 поверх моей собственной DLL... И я совершенно уверен, что kernel32.dll может быть загружен любым процессом в системе :)   -  person Uriel G    schedule 20.10.2015
comment
См. эту статью: developer.mozilla .org/en-US/docs/Mozilla/js-ctypes/ . Когда вы пытаетесь запустить kernel32, вам нужно использовать двойную обратную косую черту, если вы используете полный путь. Или вы должны просто var lib = ctypes.open('kernel32'). В приведенном выше сообщении темы для вашей пользовательской dll вы используете относительный путь, вы должны использовать полный путь, и это не может быть путь chrome, вы должны сделать из него файл uri. URI файла file://blah/blah/blah.dll   -  person Noitidart    schedule 21.10.2015
comment
@Noitidart Я скопировал kernel32 поверх своей собственной DLL, чтобы убедиться, что проблема не в самой DLL (неразрешенная зависимость, сбой в DllMain и т. д.). На всю жизнь я не могу вспомнить, где я видел, что использование .\DllName.dll в ctypes.open() возьмет его из каталога аддона - но, и это большое, но на моей машине разработки это работает! на любом другом компьютере это не так. В любом случае... Я всегда могу установить нашу вспомогательную DLL в system32, так как аддон - это просто часть более крупного продукта... так что, если ничего не поможет - это то, что я в конечном итоге сделаю...   -  person Uriel G    schedule 21.10.2015
comment
Вам не нужно устанавливать в system32, посмотрите этот рабочий аддон, который использует пользовательскую dll: /a> и этот: github.com/NoitForks/fx-sapi-test Я уверен, что ваша ошибка заключается в том, что вы не используете строку, использующую протокол file://. Если это C:\\blah.dll, сделайте ctypes.open('file://C:/blah.dll')   -  person Noitidart    schedule 21.10.2015
comment
@Noitidart Спасибо! Пожалуйста, опубликуйте как ответ, и я поставлю вам +1 :)   -  person Uriel G    schedule 27.10.2015
comment
Потрясающий! Я рад, что это сработало :)   -  person Noitidart    schedule 28.10.2015


Ответы (1)


Вам не нужно устанавливать в system32, посмотрите этот рабочий аддон, который использует пользовательскую dll: github.com/NoitForks/Firefox_addon_sdk_jsctypes и этот: github.com/NoitForks/fx-sapi-test Я уверен, что ваша ошибка в том, что вы не используете строка, использующая протокол file://. Если это C:\blah.dll, выполните ctypes.open('file://C:/blah.dll')

person Noitidart    schedule 28.10.2015
comment
Мой +1 не отображается публично, пока я не заработаю 15 очков репутации. Чувак, это похоже на игру для PS4 ;) - person Uriel G; 29.10.2015
comment
Ха-ха, это забавно, без проблем с +1. - person Noitidart; 29.10.2015
comment
После просмотра кода от NoitForks (и после добавления unpack: true в package.json) я получаю следующее сообщение — сообщение = Компонент вернул код ошибки: 0x80004002 (NS_NOINTERFACE) [ns IFileURL.file] — name = NS_NOINTERFACE — result = 2147500034 Вот мой код: var dataUrl = self.data.url(BZAddonHelper.dll); var nuri = Services.io.newURI(dataUrl,null,null); var s = nuri.QueryInterface(Ci.nsIFileURL); вар ф = s.файл(); // ‹- пробовал s.file, s.file(), а также, как в примере, nuri.QueryInterface(...).file.path var p = f.path; Любые идеи?? - person Uriel G; 01.11.2015
comment
Можете ли вы загрузить свой код в репозиторий github, я проверю его сам - person Noitidart; 01.11.2015
comment
github.com/urielgin/fftest Только что поместил kernel32.dll из моего каталога syswow64 в каталог данных аддона , только для проб... - person Uriel G; 01.11.2015
comment
Я пробовал каждую перестановку, которую можно загрузить в DLL, используя ctypes Firefox. Каждый раз, когда ctypes.open возвращается с ошибкой 126, так как он не может найти библиотеки DLL зависимостей, несмотря на то, что они находятся в той же папке, что и та, которую я пытаюсь открыть. Если я помещаю папку со всеми зависимыми DLL как часть системной переменной пути, она работает. Почему это происходит? - person Eamonn; 05.05.2016
comment
@eamonn какую dll ты пытаешься загрузить? Это dll в комплекте с аддоном? Если это так, вам придется изменить install.rdf на <em:unpack>true</em:unpack>, распаковка по умолчанию - false. Если это не пакет с вашей dll-аддоном, вы можете просто указать путь к нему. - person Noitidart; 05.05.2016
comment
@Noitidart Да, библиотеки DLL упакованы с расширением. В package.manifest есть строка: "unpack": true. Чтобы получить путь к dll, я делаю: var dll_path = Services.io.newURI(data.url('operations.dll'), null, null).QueryInterface(Ci.nsIFileURL).file.path;, который возвращает путь, например C:\Users\Eamonn\AppData\Local\Temp\1\f6ff0a5f-64b9-4953-a7a4-cb5b0a16c29c\extensions\@extension\data\operations.dll. - person Eamonn; 06.05.2016
comment
Когда я бросаю по этому пути исполняемый файл с dll, который запускает некоторые тесты на operation.dll, он работает. Я пробовал другие способы получения пути, такие как добавление «file://» в начало строки пути к файлу и использование косой черты, но Firefox не может загрузить dll при этом. - person Eamonn; 06.05.2016
comment
Я загрузил проект на github, чтобы показать проблему, с которой я столкнулся. https://github.com/EamonnLaffey/ctypes-test - person Eamonn; 06.05.2016
comment
Я разместил здесь отдельный вопрос: http://stackoverflow.com/questions/37065027/firefox-ctypes-js-cannot-open-a-dll-with-dependencies - person Eamonn; 06.05.2016