Невозможно загрузить DLL (модуль не найден HRESULT: 0x8007007E)

113

У меня есть библиотека dll с неуправляемым кодом C ++ API, который мне нужно использовать в моем приложении .NET 4.0. Но каждый метод, которым я пытаюсь загрузить свою dll, выдает ошибку:

Невозможно загрузить библиотеку DLL MyOwn.dll: указанный модуль не найден. (Исключение из HRESULT: 0x8007007E)

Я прочитал и попробовал несколько решений, которые нашел в Интернете. Ничего не работает ..

Я пробовал использовать следующие методы:

[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);

Какие-либо предложения?

Ингимар Андрессон
источник

Ответы:

90

Из того, что я помню в Windows, порядок поиска dll следующий:

  1. Текущий каталог
  2. Системная папка C:\windows\system32 or c:\windows\SysWOW64(для 32-битного процесса на 64-битном компьютере).
  3. Чтение из Pathпеременной окружения

Кроме того, я бы проверил зависимости DLL, обходчик зависимостей, поставляемый с Visual Studio, может помочь вам здесь, его также можно скачать бесплатно: http://www.dependencywalker.com

дисплей101
источник
4
обнаружил, что некоторые зависимости отсутствуют (Oracle и некоторые DLL из IE). Необходимо установить Oracle, так как моя dll зависит от этого ... тогда я узнаю :) Обнаружил проблему с DependencyWalker;)
Ingimar Andresson
Не беспокойтесь, это избавило меня от многих часов чесания головы, отличный маленький инструмент! :-)
display101
1
+1 Кейту Халлигану за предложение DependencyWalker. Он сказал мне, что не все зависимости имеют один и тот же тип процессора (x86 / x64). Я скопировал все файлы с одинаковым типом процессора в папку bin моего приложения, и проблема была решена.
DiligentKarma
6
В каждой DLL, которую я могу найти в своей системе, есть DependencyWalker, утверждающий, что есть ошибка с разными типами ЦП - даже с System.Web.Mvc.dll. Здесь какая-то ложная тревога.
PandaWood 02
2
В моем случае проблема заключалась в попытке загрузить C ++ DLL, скомпилированную для отладки. Для этого нужна среда отладки C ++, а это значит, что вам необходимо установить Visual Studio. Или перекомпилируйте DLL для выпуска и установите распространяемую среду выполнения C ++.
RenniePet
42

Вы можете использовать инструмент dumpbin, чтобы узнать необходимые зависимости DLL:

dumpbin /DEPENDENTS my.dll

Это скажет вам, какие библиотеки DLL необходимо загрузить. Особенно обратите внимание на MSVCR * .dll. Я видел, что ваш код ошибки возникает, когда не установлен правильный распространяемый компонент Visual C ++.

Вы можете получить «Распространяемые пакеты Visual C ++ для 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, но не с помощью Распространяемого пакета.

Энтони Хейворд
источник
5
добавление распространяемых компонентов VS C ++ было для меня этим! требуется v10.0 (2010). Спасибо, мучо !!!
Тьяго Силва
Есть ли способ узнать, требуются ли 64-разрядные или 32-разрядные версии распространяемых файлов?
BVB
1
dumpbin / ALL сообщит вам, является ли my.dll x86 или x64
Энтони Хейворд,
1
Для тех, кто все еще страдает от этой проблемы, если вы используете debugдвоичный файл, версия распространяемых компонентов среды выполнения C ++ должна быть точно такой же, как и в том месте, где вы ее создали.
skyline75489
Комментарий @ skyline75489 спас мне день. Библиотека C ++ отлично работала на моей машине, но не загружалась повсюду из-за того, что VS связала ее с отладочной версией msvcr.
шпион
14

Это «кладж», но вы можете, по крайней мере, использовать его для проверки работоспособности: попробуйте жестко указать путь к DLL в своем коде

[DllImport(@"C:\\mycompany\\MyDLL.dll")]

Было сказано, что; в моем случае работа, dumpbin /DEPENDENTSпредложенная @ anthony-hayward, и копирование более 32-разрядных версий перечисленных там DLL в мой рабочий каталог решило эту проблему для меня.

Сообщение немного вводит в заблуждение, потому что это не "моя" dll, которую нельзя загрузить - это зависимости

Черный
источник
12

DLL должна находиться в папке bin.

В Visual Studio я добавляю dll в свой проект (НЕ в «Ссылки», а «Добавить существующий файл»). Затем установите для свойства «Копировать в выходной каталог» для dll значение «Копировать, если новее».

Джереми Томпсон
источник
11

Попробуйте ввести полный путь к dll. Если не работает, попробуйте скопировать dll в папку system32.

Headpuster
источник
3
нормально ли иметь все зависимости в папке System32 и моей dll где-то еще?
Ingimar Andresson
Зависимости также будут искать в соответствии с порядком пути поиска dll в Windows, как указано в stackoverflow.com/a/9003290/4434329
4

Убедитесь, что все зависимости вашей собственной dll присутствуют рядом с dll или в System32.

Феличе Поллано
источник
4

Есть одна очень забавная вещь (имеющая техническое значение), которая может напрасно тратить ваши часы, поэтому подумайте о том, чтобы поделиться ею здесь -

Я создал проект консольного приложения ConsoleApplication1и проект библиотеки классов ClassLibrary1.

Весь код, который делал p / invoke, присутствовал в ClassLibrary1.dll. Поэтому перед отладкой приложения из Visual Studio я просто скопировал неуправляемую сборку C ++ ( myUnmanagedFunctions.dll) в \bin\debug\каталог ClassLibrary1проекта, чтобы ее можно было загрузить во время выполнения с помощью среды CLR.

Я продолжал получать

Невозможно загрузить DLL

ошибка часов. Позже я понял, что все такие неуправляемые сборки, которые должны быть загружены, необходимо скопировать в \bin\debugкаталог запускаемого проекта, ConsoleApplication1который обычно представляет собой форму win, консоль или веб-приложение.

Поэтому, пожалуйста, будьте осторожны: Current Directoryв принятом ответе на самом деле означает Current Directoryосновной исполняемый файл, с которого запускается процесс вашего приложения. Выглядит очевидным, но временами может быть не так.

Извлеченный урок - всегда помещайте неуправляемые библиотеки DLL в тот же каталог, что и исполняемый файл запуска, чтобы его можно было найти.

RBT
источник
Это исправило и меня. Хотя
Шон Дагган,
@SeanDuggan, потому что это «динамическая библиотека компоновки», означающая, что она используется (загружается) во время выполнения, в отличие от статических библиотек, которые используются во время компоновки.
m4l490n
Я попытался добавить DLL в bin\Debugи obj\Debugкаталоги , и я постоянно получаю «Не удается загрузить DLL»
m4l490n
3

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

Крис О
источник
2

Убедитесь, что вы установили цель сборки платформы на x86 или x64, чтобы она была совместима с вашей библиотекой DLL, которая может быть скомпилирована для 32-разрядной платформы.

Grantly
источник
2

Если проекты DLL и .NET находятся в одном решении и вы хотите каждый раз компилировать и запускать оба, вы можете щелкнуть правой кнопкой мыши свойства проекта .NET, события сборки, а затем добавить что-то вроде следующего в событие Post-build командная строка:

copy $(SolutionDir)Debug\MyOwn.dll .

По сути, это строка DOS, и вы можете настроить ее в зависимости от того, для чего создается ваша DLL.

SharpC
источник
2

У меня была такая же проблема, когда я развернул приложение для тестирования ПК. Проблема заключалась в том, что ПК для разработки msvcp110d.dllиmsvcr110d.dll , но не тестовый компьютер.

Я добавил модуль слияния Visual Studio C ++ 11.0 DebugCRT (x86) в InstalledSheild, и он сработал. Надеюсь, это будет полезно для кого-то еще.

kakopappa
источник
2

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

Именно это и произошло в моем случае. Надеюсь, это поможет кому-то другому.

Rahatur
источник
1

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

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

Эухенио Миро
источник
1

Установка : 32-битная Windows 7

Контекст : установлен драйвер PCI-GPIB, через который мне не удалось связаться из-за вышеупомянутой проблемы.

Краткий ответ : переустановите драйвер.

Длинный ответ : я также использовал Dependency Walker , который выявил несколько недостающих модулей зависимостей. Сразу подумал, что это, должно быть, неудачная установка драйвера. Я не хотел проверять и восстанавливать каждый отсутствующий файл.

Тот факт, что мне не удалось найти программу удаления в разделе «Программы и компоненты панели управления», является еще одним признаком неправильной установки. Мне пришлось вручную удалить пару * .dll в \ system32 и разделах реестра, чтобы можно было переустановить драйвер.

Проблема исправлена.

Неожиданной частью было то, что не все модули зависимостей были разрешены. Тем не менее, теперь можно сослаться на интересующую библиотеку * .dll.

icernos
источник
1

Я столкнулся с той же проблемой, в моем случае у меня было два 32-битных компьютера. Один с установленным .NET4.5, а другой был свежим ПК.

моя 32-битная cpp dll (сборка в режиме выпуска) отлично работала с установленным .NET ПК, но не со свежим ПК, где я получил следующую ошибку

Невозможно загрузить DLL 'PrinterSettings.dll': указанный модуль не найден. (Исключение из HRESULT: 0x8007007E)

Ну наконец то,

Я только что построил свой проект в конфигурации режима отладки, и на этот раз моя dll cpp работала нормально.

Абу Мухаммад
источник
0

Также столкнулся с той же проблемой при использовании неуправляемого файла dll c / c ++ в среде c #.

1. Проверял совместимость dll с 32-битным или 64-битным процессором.

2.Проверены правильные пути к папке DLL .bin, system32 / sysWOW64 или указанному пути.

3.Проверено, отсутствуют ли файлы PDB (Program Database). Это видео дает вам лучшее представление о файлах .

При запуске 32-битного двоичного кода C / C ++ в 64-битной системе это могло произойти из-за несовместимости платформы. Вы можете изменить его в меню «Сборка»> «Диспетчер конфигурации».

Юреш Карунанаяке
источник
0

Я столкнулся с той же проблемой при импорте C ++ Dll в .Net Framework +4, я снял флажок Project-> Properties-> Build-> Prefer 32-bit, и это решило для меня.

Мамо Ганди
источник