"Была сделана попытка загрузить программу с неверным форматом", даже если платформы одинаковы

Я вызываю функции из 32-разрядной неуправляемой библиотеки DLL в 64-разрядной системе. Что я получаю это:

BadImageFormatException: была предпринята попытка загрузить программу с неверным форматом. (Исключение из HRESULT: 0x8007000B)

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

DLL не повреждены или что-то еще, потому что я могу использовать их с другими программами (для которых у меня нет источника). Я подумал, что, возможно, он не нашел зависимости, но я проверил, и все они там. Плюс, это не бросило бы DllNotFoundException в таком случае?

Что еще я могу сделать? И прежде чем вы скажете: "Вместо этого используйте 64-разрядную неуправляемую DLL", позвольте мне отметить, что ее нет.;)

26 ответов

Решение

Каким-то образом флажок " Сборка" в Configuration Manager не был отмечен для моего исполняемого файла, поэтому он все еще работал со старой сборкой Any CPU. После того, как я это исправил, Visual Studio пожаловалась, что не может отладить сборку, но это было исправлено путем перезапуска.

Если вы попытаетесь запустить 32-разрядные приложения на IIS 7 (и / или на компьютере с 64-разрядной ОС), вы получите ту же ошибку. Итак, в IIS 7 щелкните правой кнопкой мыши пул приложений приложений и перейдите в раздел "Дополнительные параметры" и измените "Включить 32-разрядные приложения" на "ИСТИНА".

Перезапустите ваш сайт, и он должен работать.

В Visual Studio щелкните правой кнопкой мыши свой проект -> На левой панели перейдите на вкладку Build,

Свойства проекта, вкладка сборки

в разделе Platform Target выберите x86 (или, в более общем случае, архитектуру, соответствующую библиотеке, на которую вы ссылаетесь)

Свойства проекта, цель платформы

Я надеюсь, что это помогает кому-то!:)

Если вы столкнулись с этой ошибкой, когда нажимаете зеленую кнопку со стрелкой, чтобы запустить приложение, но по-прежнему хотите запустить приложение в 64-разрядной версии. Вы можете сделать это в VS 2013, 2015 и 2017

Перейдите: Инструменты> Параметры> Проекты и решения> Веб-проекты> Использовать 64-разрядную версию IIS Express

У меня тоже была эта проблема. Перепробовал все предложения здесь, но они не помогли.

Я нашел еще одну вещь, чтобы проверить, что исправило это для меня. В Visual Studio щелкните правой кнопкой мыши проект и откройте "Свойства". Нажмите на вкладку "Компиляция" (или "Сборка"), а затем нажмите "Дополнительные параметры компиляции" внизу.

Проверьте выпадающий "Target CPU". Он должен соответствовать "Платформе", которую вы строите. То есть, если вы создаете "Любой ЦП", тогда "Целевой ЦП" должен сказать "Любой ЦП". Просмотрите все свои платформы, сделав их активными, и проверьте этот параметр.

Если вы используете Любой ЦП, вы можете столкнуться с этой проблемой, если установлен флажок Предпочитать 32-разрядный:

Убедитесь, что вы сняли эту опцию во вкладке Build свойства проекта!

В моем случае я использовал нативную DLL в C#. Эта DLL зависела от нескольких других отсутствующих DLL. Как только эти другие библиотеки были добавлены, все работало.

1: перейдите к: Инструменты> Параметры> Проекты и решения> Веб-проекты> Использовать 64-разрядную версию IIS Express 2: измените настройки ниже для проекта веб-службы.

У нас была похожая проблема, и нам удалось ее исправить, установив целевую платформу на x86.

Немного не по теме для этого поста, но поиск этого сообщения об ошибке привел меня сюда.

Если вы собираете систему через систему Team и получаете эту ошибку, вкладка процесса определения сборки имеет параметр "MSBuild Platform". Если для этого параметра установлено значение "Авто", вы можете столкнуться с этой проблемой. Изменение его на "X86" также может устранить ошибку.

В Visual Studio 2019 у меня была аналогичная проблема, когда я хотел запустить тесты (MSTest прямо из VS). В моем случае у меня была только собственная библиотека x64, и я получил это сообщение об ошибке. Сначала я подумал, что это потому, что Visual Studio работает как x86, но эта страница помогла мне решить проблему:

Запустить модульный тест как 64-битный процесс

Это говорит

  1. Настройте свои проекты на любой процессор
  2. Явно определите архитектуру процессора

Я сделал и то, и другое (я явно установил x64), после чего мои тесты начали работать.

Опираясь на ответ @paibamboo

Он сказал: Перейти к: Инструменты> Параметры> Проекты и решения> Веб-проекты> Использовать 64-разрядную версию IIS Express

Мой коллега проверил этот флажок (он явно искал его), но имел сообщение об ошибке в вопросе. Через несколько часов он снял флажок и снова проверил. И вот, код теперь работает с успехом.

Похоже, что есть два места, где состояние этого ящика не сохранено, которое стало несинхронным. Отпроверка и повторная проверка синхронизировались снова.

Вопрос для более знающих пользователей: было ли обновление или что-то на прошлой неделе (для VS 2015), которые отменили синхронизацию состояний?

В моем случае это было неправильное содержание файла. DLL была загружена из Интернета, но содержимое DLL было HTML-страницей:D Попробуйте проверить, является ли это двоичным файлом, если он кажется правильным DLL:)

Также посмотрите этот ответ, который решил ту же проблему для меня.

Написал Luis Mack 5/12/2010 в 8:50 AM Я обнаружил ту же проблему, только для конкретного проекта при компиляции на 64-битной машине. Исправление, которое SEEMS работает, состоит в том, чтобы вручную изменять один символ в потоке изображения КАЖДЫЙ РАЗ, когда пользовательский контроль или форма редактируются в конструкторе.

 AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w

Изменить на

 AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w

То есть 00LjAuMC4w обратно в 0yLjAuMC4w в конце строки (00 назад в 0y)

В моем случае я выполнял тесты через MSTest и обнаружил, что развертываю 32-битную и 64-битную DLL в каталог test. Программа отдавала предпочтение 64-битной DLL и вызывала ее сбой.

TL; DR Убедитесь, что в тестах используются только 32-битные библиотеки DLL.

В моем случае я использую крошечный.exe, который перезагружает ссылочные библиотеки DLL через Reflection. Так что я просто делаю эти шаги, которые спасают мой день:

Из свойств проекта в обозревателе решений на вкладке "Сборка" я выбираю целевой платформу от x86

Если вы импортируете неуправляемую DLL, используйте

CallingConvention = CallingConvention.Cdecl 

в вашем методе импорта DLL.

Я решил эту проблему способом "Windows". После проверки всех моих настроек, очистки решения и его восстановления я просто закрыл решение и снова открыл его. Тогда это сработало, поэтому VS, вероятно, не избавился от некоторых вещей во время уборки. Когда логические решения не работают, я обычно обращаюсь к нелогичным (или, казалось бы, нелогичным). Windows не подводит меня.:)

Я смог решить эту проблему, сопоставив мою версию сборки с версией.NET на сервере.

Я дважды щелкнул.exe, чтобы посмотреть, что произойдет, и он сказал мне установить 4.5....

Так что я понизился до 4.0, и это сработало!

Поэтому убедитесь, что ваши версии совпадают. Он отлично работал на моем устройстве dev, но на сервере была более старая версия.NET.

У нас была такая же проблема в ядре.NET. Решение состояло в том, чтобы загрузить 32-разрядную среду выполнения.netcore и получить цель вашего проекта. x86

В вашей csproj добавление файла

  <PropertyGroup>
    <PlatformTarget>x86</PlatformTarget>  
  </PropertyGroup>

  <PropertyGroup>
    <RunCommand Condition="'$(PlatformTarget)' == 'x86'">$(MSBuildProgramFiles32)\dotnet\dotnet</RunCommand>    
  </PropertyGroup>

Это использовалось для компьютера с Windows, вам нужно будет настроить пути и так далее для Linux/OSX

Для ядра .net убедитесь, что Ijwhost.dll находится в выходном каталоге, иногда он не копируется, и это вызовет ошибку. См. https://github.com/dotnet/runtime/issues/38231, а также /questions/50593731/nevernyij-format-izobrazheniya-pri-zapuske-upravlyaemoj-sborki-c-cli-v-net-core/50593743#50593743

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

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

Решение заключалось в том, чтобы сначала очистить папку публикации, а затем это сработало.

(в качестве альтернативы установите для параметра «удалить существующие файлы» значение true)

Другой причиной, которая может вызвать это исключение, является отсутствие распространяемых компонентов C++ для целевой платформы вашей библиотеки DLL. Мне было трудно это выяснить при тестировании на виртуальной машине.

Также обратите внимание, что версия используемого dll-файла (файлов) (в моем случае «WebView2Loader.dll»), которая используется, очень важна. У меня была почти такая же проблема с «Microsoft.WebView2.FixedVersionRuntime.101.0.1210.39.x64», когда я пытался использовать компонент WebView2 в оснастках MMC с типами «HTMLView» или «FormView».

Я просто скопировал указанный файл dll по правильному пути, который был доступен для проекта (вы можете просто поместить его рядом с выходными файлами проекта, чтобы проверить его), а затем браузер WebView2 начал работать, как и ожидалось. Сообщения об ошибках Microsoft иногда (по крайней мере, в моем случае) немного вводили в заблуждение и не давали достаточной и точной информации.

Я получил «BadImageFormatException», который обычно возникает, когда вы смешиваете цели платформы (например, используете файл dll, скомпилированный в X64, в приложении, предназначенном для x86, или наоборот) или смешиваете собственный код и .NET, но это не было моей проблемой вообще. Я надеюсь, что это поможет тому, кто может застрять.

У меня также была эта проблема, когда я хочу вызвать собственную DLL из С#/WPA. Следующие шаги работают для моего проекта. Свойства-> Сборка-> Целевая платформа x64/x86(измените эту опцию, тогда она будет работать).

Другие вопросы по тегам