Не удалось загрузить DLL (модуль не найден HRESULT: 0x8007007E)
У меня есть библиотека dll с неуправляемым кодом С++ API, который мне нужно использовать в моем приложении .NET 4.0. Но каждый метод, который я пытаюсь загрузить с моей DLL, я получаю:
Невозможно загрузить DLL 'MyOwn.dll': указанный модуль не найден. (Исключение из HRESULT: 0x8007007E)
Я прочитал и попробовал решения severa, которые я нашел в Интернете. Ничего не работает.
Я попытался использовать следующие методы:
[DllImport("MyOwn.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs((UnmanagedType.I4))]
public static extern Int32 MyProIni(string DBname, string DBuser_pass,
string WorkDirectory, ref StringBuilder ErrorMessage);
Когда я попытался выполнить эту статью, и когда я запускаю этот пример (из загруженного кода), он запускается без проблем (используемая dll находится в bin/debug папка)
Я скопировал свою dll (вместе со всеми файлами в зависимости от моей папки bin).
Я также пробовал этот подход, но получил ту же ошибку:
[DllImportAttribute(MyOwnLibDllPath, EntryPoint="TMproIni")]
[return: MarshalAs(UnmanagedType.I4)]
public static extern int MyproIni(string DBname, string DBuser_pass,
string WorkDirectory, ref StringBuilder ErrorMessage);
Любые предложения?
Ответы
Ответ 1
Из того, что я помню в Windows, порядок поиска для dll:
- Текущий каталог
- Системная папка,
C:\windows\system32 or c:\windows\SysWOW64
(для 32-разрядного процесса в 64-битной ячейке).
- Чтение из переменной среды
Path
Кроме того, я бы проверял зависимости DLL, хост зависимостей, предоставляемый Visual Studio, может помочь вам здесь, он также может быть загружен бесплатно: http://www.dependencywalker.com
Ответ 2
Вы можете использовать инструмент dumpbin для поиска необходимых зависимостей DLL:
dumpbin /DEPENDENTS my.dll
Это расскажет вам, какие DLL файлы должны загружать DLL. Особенно обратите внимание на MSVCR *.dll. Я видел, что ваш код ошибки возникает, когда не установлен Redistributable Visual С++.
Вы можете получить "Распространяемые пакеты Visual С++ для Visual Studio 2013" с веб-сайта Microsoft. Он устанавливает c:\windows\system32\MSVCR120.dll
В имени файла 120 = 12.0 = Visual Studio 2013.
Будьте осторожны, чтобы у вас была правильная версия Visual Studio (10.0 = VS 10, 11 = VS 2012, 12.0 = VS 2013...), правильная архитектура (x64 или x86) для вашей целевой платформы DLL, а также вам нужно будьте осторожны в сборке отладки. Отладочная сборка DLL зависит от MSVCR120d.dll, которая является отладочной версией библиотеки, которая устанавливается с помощью Visual Studio, но не с помощью распространяемого пакета.
Ответ 3
Попробуйте ввести полный путь к dll.
Если это не сработает, попробуйте скопировать dll в папку system32.
Ответ 4
DLL должна находиться в папке bin.
В Visual Studio я добавляю dll в свой проект (НЕ в ссылках, но "Добавить существующий файл" ). Затем установите для свойства "Копировать в выходной каталог" для dll значение "Копировать, если новое".
Ответ 5
Убедитесь, что все зависимости вашей собственной DLL находятся рядом с dll или в System32
.
Ответ 6
Есть одна очень забавная вещь (и имеет техническую значимость), которая может растратить ваши часы, поэтому подумал о том, чтобы поделиться ею здесь -
Я создал проект консольного приложения ConsoleApplication1
и проект библиотеки классов ClassLibrary1
.
Весь код, который делал p/invoke, присутствовал в ClassLibrary1.dll
. Поэтому перед отладкой приложения из visual studio я просто скопировал неуправляемую сборку С++ (myUnmanagedFunctions.dll
) в каталог \bin\debug\
проекта ClassLibrary1
, чтобы он мог быть загружен в среду выполнения CLR.
Я продолжал получать
Невозможно загрузить DLL
ошибка в течение нескольких часов. Позже я понял, что все неуправляемые сборки, которые необходимо загрузить, необходимо скопировать в каталог \bin\debug
стартового проекта ConsoleApplication1
, который обычно представляет собой форму выигрыша, консольное или веб-приложение.
Итак, будьте осторожны, Current Directory
в принятом ответе фактически означает Current Directory
основного исполняемого файла, с которого начинается процесс приложения. Похоже на очевидную вещь, но иногда это может быть не так.
Извлеченный урок. Всегда размещайте неуправляемые DLL в том же каталоге, что и исполняемый файл запуска, чтобы убедиться, что он может быть найден.
Ответ 7
Это "kludge" , но вы могли бы хотя бы использовать его для проверки на работоспособность:
Попробуйте жестко кодировать путь к DLL в вашем коде
[DllImport(@"C:\\mycompany\\MyDLL.dll")]
Сказав это; в моем случае с запуском dumpbin /DEPENDENTS
, как было предложено @anthony-hayward, и копирование через 32-разрядных версий DLL, перечисленных там в моем рабочем каталоге, решило эту проблему для меня.
Сообщение просто немного вводит в заблуждение, потому что это не "моя" DLL, которая не может быть загружена - это зависимости
Ответ 8
Включите ведение журнала фьюжн, см. этот вопрос за советом о том, как это сделать. Отладка проблем с загрузкой приложений смешанного режима может быть правильной болью. Запуск слияния может быть большой помощью.
Ответ 9
Убедитесь, что вы устанавливаете платформу Build Platform Target на x86 или x64, чтобы она была совместима с вашей DLL, которая может быть скомпилирована для 32-битной платформы.
Ответ 10
Если проекты DLL и .NET находятся в одном и том же решении, и вы хотите их компилировать и запускать каждый раз, вы можете щелкнуть правой кнопкой мыши по свойствам проекта .NET, постройкам событий, а затем добавить что-то вроде следующего в сообщение Командная строка события:
copy $(SolutionDir)Debug\MyOwn.dll .
В основном это строка DOS, и вы можете настроить ее на основе того, где строится ваша DLL.
Ответ 11
У меня была такая же проблема, когда я развернул свое приложение для тестирования ПК. Проблема заключалась в разработке ПК с msvcp110d.dll
и msvcr110d.dll
, но не на тестовом ПК.
Я добавил "Слиточный модуль Visual Studio С++ 11.0 DebugCRT (x86)" в InstalledSheild, и он сработал. Надеюсь, это будет полезно для кого-то другого.
Ответ 12
Настройка: 32-разрядная версия Windows 7
Контекст: установлен драйвер PCI-GPIB, с которым я не смог связаться из-за вышеупомянутой проблемы.
Короткий ответ: переустановите драйвер.
Длительный ответ:
Я также использовал Dependency Walker, в котором было указано несколько отсутствующих модулей зависимостей. Сразу же я подумал, что это была неудачная установка драйвера. Я не хотел проверять и восстанавливать каждый отсутствующий файл.
Тот факт, что я не смог найти деинсталлятор в разделе "Программы и функции панели управления", является еще одним показателем плохой установки. Мне пришлось вручную удалить пару *.dll в \system32 и ключи реестра, чтобы разрешить повторную установку драйвера.
Исправлена проблема.
Неожиданная часть заключалась в том, что не все модули зависимостей были разрешены. Тем не менее, теперь можно указать *.dll интерес.
Ответ 13
Я столкнулся с той же проблемой, в моем случае у меня было два 32-битных ПК. Один с установленным .NET4.5, а другой был свежим ПК.
Мой 32-битный cpp dll (Release mode build) работал нормально с установленным ПК .NET, но не со свежим ПК, где я получил следующую ошибку
Невозможно загрузить DLL "PrinterSettings.dll": указанный модуль не найден. (Исключение из HRESULT: 0x8007007E)
в конце концов,
Я только что построил свой проект в конфигурации режима отладки, и на этот раз мой cpp dll работал нормально.
Ответ 14
Я думаю, что ваша неуправляемая библиотека нуждается в манифесте.
Здесь, как добавить его в свой двоичный файл. и здесь.
Таким образом, в вашем окне может быть установлено несколько версий распространяемой библиотеки, но только одно из них должно удовлетворять вашему приложению, и это может быть не по умолчанию, поэтому вам нужно сообщить системе, что вам нужна ваша библиотека, поэтому манифест.
Ответ 15
Также столкнулся с той же проблемой при использовании неуправляемого файла dll c/c++ в среде С#.
1.Проверил совместимость dll с 32-битным или 64-битным процессором.
2.Проверены правильные пути к папке DLL.bin, system32/sysWOW64 или указанному пути.
3.Проверено, отсутствуют ли файлы PDB (база данных программ). Это видео дает вам лучшее представление о файлах pdb.
При запуске 32-битного двоичного кода C/c++ в 64-битной системе это может произойти из-за несовместимости платформы. Вы можете изменить его из Build> Configuration manager.