Ошибка LoadLibrary с кодом ошибки 126, если приложение запускается из опции установки - PullRequest
1 голос
/ 29 марта 2019

У меня есть два приложения, и я устанавливаю их в разные папки, пусть они называются приложениями A и B, A является основным приложением, а B является COM-модулем, A запускает B через COM API после запуска A, некоторые библиотеки DLL должны бытьзагружается B, пока B запускается, если я запускаю A двойным щелчком по ярлыку A, все в порядке, но если я устанавливаю A и запускаю A, отметив параметр запуска A в последнем диалоговом окне установки, то Bзапущен, но загрузка одной из DLL не удалась с кодом ошибки 126 (ERROR_MOD_NOT_FOUND), если я выйду и перезапущусь, дважды щелкнув по ярлыку, он снова заработает.

Уже выполните несколько операций поиска в Google, и, похоже, единственная разница между запуском из ярлыка и установкой - это текущий каталог, т. Е. Если запуск из установки, то же самое, что запуск из папки пакета установщика с помощью cmd, например open cmd, переключитесь напапку установочного пакета, затем запустите приложение A с полным путем, я попробовал это, также работает хорошо.

Мой установочный пакет собран с помощью installshield.

У кого-нибудь есть какие-либо подсказки по этой проблеме?

  1. Уже попробуйте переключить текущий каталог на путь установки A и B, оба не могут решить эту проблему.
  2. Уже попробуйте установить в каталоге dll путь установки B, который также является путем сбойной DLL, тоже не работает.
  3. Уже попробуйте загрузить DLL с полным путем, также не удалось.
    //SetCurrentDirectory(L"C:\Program Files (x86)\install path of A"); <<<not work
    //SetCurrentDirectory(L"C:\Program Files (x86)\install paht of B");   <<<not work
    //SetDllDirectory(L"C:\Program Files (x86)\DLL path");   <<<not work
    //m_hLibrary = LoadLibrary((LPCWSTR)DLL full path);   //not work
    m_hLibrary = LoadLibrary((LPCWSTR)dllName.c_str());   //failed with error code 126

1 Ответ

0 голосов
/ 04 апреля 2019

Похоже, вы диагностировали симптомы. Их решение может быть сложным, так как по крайней мере некоторые версии InstallShield вызывают API-интерфейсы, которые снижают возможность загрузки неожиданных DLL-файлов до создания папки приложения. Похоже, что последствия этих вызовов переносятся на ваш процесс, когда вы запускаете его непосредственно из установщика.

Итак, во-первых, упрощенный вариант 1: уберите опцию, чтобы запустить ваше приложение с последней страницы мастера. Пуф, проблема уходит. Но это, вероятно, делает кого-то несчастным.

Вместо этого давайте попробуем погрузиться в происходящее. В зависимости от конкретной версии InstallShield, он может вызывать некоторую комбинацию API, но наиболее вероятным виновником является вызов SetDllDirectory(L"");. Согласно некоторым быстрым исследованиям , это должно влиять только на неявно загруженную DLL в дочерних процессах, но это не тот сценарий, который вы описываете.

Вы попытались отменить этот вызов, явно добавив каталог; вот мои рекомендуемые (но не проверенные) варианты 2 и 3:

...