Rozwiązywanie problemów z błędem BadImageFormatException

107

Mam usługę Windows napisaną w C # przy użyciu Visual Studio 2010 i przeznaczoną dla pełnego .NET Framework 4. Kiedy uruchamiam z kompilacji debugowania, usługa działa zgodnie z oczekiwaniami. Jednak po uruchomieniu go z kompilacji wydania otrzymuję wyjątek System.BadImageFormatException (szczegóły poniżej). Szukałem rozwiązania w Internecie, ale jak dotąd wszystko, co znalazłem, nie pomogło mi znaleźć rozwiązania.

Problem występuje zarówno w 64-bitowym (deweloperskim) systemie Windows 7, jak i 32-bitowym (docelowym) systemie Windows XP z dodatkiem SP3.

Oto, czego próbowałem do tej pory:

  • Zweryfikowane ustawienia kompilacji, takie jak Platform Target, są takie same (x86).
  • Użyto peverify z opcją / verbose, aby upewnić się, że pliki binarne zestawu są prawidłowe.
  • Używa fuslogvw do wyszukiwania problemów z ładowaniem.
  • Użył CheckAsm do wyszukania brakujących plików lub zestawów.

Wszystkie te kontrole niczego nie zmieniły. Poniżej zamieściłem pełny tekst informacji o wyjątku, a niektóre nazwy zostały zmienione, aby chronić sekrety moich korporacyjnych mistrzów.

System.BadImageFormatException nie został obsłużony
  Komunikat = nie można załadować pliku lub zestawu „XxxDevices, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null” lub jednej z jego zależności. Podjęto próbę załadowania programu o nieprawidłowym formacie.
  Źródło = XxxDevicesService
  FileName = XxxDevices, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null
  FusionLog = Menedżer zespołu załadowany z: C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ clr.dll
Uruchomiony pod plikiem wykonywalnym c: \ Dev \ TeamE \ bin \ Release \ XxxDevicesService.vshost.exe
--- Następuje szczegółowy dziennik błędów. 

=== Informacje o stanie przed wiązaniem ===
LOG: Użytkownik = XXX
LOG: DisplayName = XxxDevices, wersja = 1.0.0.0, kultura = neutralna, PublicKeyToken = null
 (W pełni określone)
LOG: Appbase = file: /// c: / Dev / TeamE / bin / Release /
LOG: Początkowa ścieżka PrivatePath = NULL
Wywołanie zestawu: XxxDevicesService, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null.
===
LOG: To powiązanie rozpoczyna się w domyślnym kontekście ładowania.
LOG: Korzystanie z pliku konfiguracyjnego aplikacji: c: \ TeamE \ bin \ Release \ XxxDevicesService.vshost.exe.Config
LOG: Korzystanie z pliku konfiguracyjnego hosta: 
LOG: Używając pliku konfiguracyjnego komputera z C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ config \ machine.config.
LOG: Zasady nie są obecnie stosowane do odwołania (powiązanie zestawu prywatnego, niestandardowego, częściowego lub opartego na lokalizacji).
LOG: Próba pobrania nowego pliku URL: /// c: /TeamE/bin/Release/XxxDevices.DLL.
BŁĄD: nie można ukończyć instalacji zestawu (hr = 0x8007000b). Sondowanie zakończone.

  Ślad stosu:
       w XxxDevicesService.Program.Main (String [] args)
       w System.AppDomain._nExecuteAssembly (zestaw RuntimeAssembly, String [] args)
       w Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly ()
       at System.Threading.ExecutionContext.Run (ExecutionContext ExecutionContext, wywołanie zwrotne ContextCallback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run (ExecutionContext ExecutionContext, wywołanie zwrotne ContextCallback, stan obiektu)
       w System.Threading.ThreadHelper.ThreadStart ()
  InnerException: 

źródło
czy w ogóle mieszasz kod natywny / .net?
Keith Nicholas
1
Jesteś na właściwej ścieżce, że ten wyjątek jest powiązany z różnicami x86 / x64 bit. Zakładam, że to nie jest aplikacja internetowa, prawda? Jaki jest także rodzaj montażu XxxDevicesService? Czy jest kompilowany dla konkretnej platformy (np. 32-bitowej)? Jeśli tak, musisz skompilować swoją platformę do wersji 32-bitowej.
Reddog

Odpowiedzi:

121

Zweryfikowane ustawienia kompilacji, takie jak Platform Target, są takie same (x86).

To nie jest to, co mówi dziennik awarii:

Menedżer zespołu załadowany z: C: \ Windows \ Microsoft.NET \ Framework64

Zwróć uwagę na 64 w nazwie, to jest strona główna 64-bitowej wersji frameworka. Ustaw ustawienie platformy docelowej w projekcie EXE , a nie w projekcie biblioteki klas. Projekt XxxDevicesService EXE określa bitowość procesu.

Hans Passant
źródło
6
Podczas sprawdzania projektu EXE - sprawdź zarówno Debuguj, jak i Wydanie. : /
chris
44

Po tym, jak przestałem walić głową w biurko, myśląc o całym tygodniu, który spędziłem na rozwiązywaniu tego problemu, dzielę się tym, co mi pomogło. Mam 64-bitowy, 32-bitowy klient Oracle dla systemu Windows 7 i mój projekt MVC 5 jest ustawiony na działanie na platformie x86 ze względu na bitowość Oracle. Ciągle otrzymuję te same błędy:

Nie można załadować pliku lub zestawu „Oracle.DataAccess” lub jednej z jego zależności. Podjęto próbę załadowania programu o nieprawidłowym formacie.

Ponownie załadowałem pakiety NuGet, użyłem kopii bibliotek DLL, które działały dla innych w różnych aplikacjach, ustawiłem bazę kodu w zestawie zależnym tak, aby wskazywała na folder bin mojego projektu, próbowałem CopyLocal jako true lub false, próbowałem wszystkiego. W końcu miałem wystarczająco dużo roboty, chciałem sprawdzić swój kod, a jako nowy kontrahent nie skonfigurowałem subversion. Szukając sposobu na podłączenie go do VS, potknąłem się o odpowiedź. Okazało się, że zadziałało odznaczenie opcji „Użyj 64-bitowej wersji IIS Express dla witryn sieci Web i projektów” w sekcji Projekty i rozwiązania => Projekty sieci Web w menu Narzędzia => Opcje.

Joey Morgan
źródło
3
Co za uratowanie życia !! Dziękuję Ci. Dla mnie musiałem to sprawdzić, ponieważ mój projekt jest efektywnie x64. Dzięki jeszcze raz!!!
viper
Po całej pomocy, jaką tutaj otrzymałem, bardzo się cieszę, że mogłem przekazać jej część dalej!
Joseph Morgan
3
W przypadku korzystania z lokalnych usług IIS upewnij się, że opcja „Włącz aplikacje 32-bitowe” puli aplikacji (w obszarze Ustawienia zaawansowane) ma wartość Prawda .
Eric Eskildsen
Dodatek do komentarza @ EricEskildsena powyżej o „włączaniu aplikacji 32-bitowych” w puli aplikacji, nawet jeśli nie chcesz tego robić w środowisku na żywo, przestawienie tego przełącznika może dostarczyć dodatkowych wskazówek, czy masz do czynienia z 32 -bitowym -bit / 64-bitowy problem lub coś innego.
CVn
Bum! To było to.
itslittlejohn
21

Okazało się, że zadziałało zaznaczenie opcji „Użyj 64-bitowej wersji IIS Express dla witryn sieci Web i projektów” w sekcji Projekty i rozwiązania => Projekty sieci Web w menu Narzędzia => Opcje.

Lucy Zhang
źródło
jesteś zbawicielem. +1
Amit Kumar,
Ponownie zainstalowałem VS i rozwiązałem ten problem (dziękuję - to rozwiązanie zadziałało). Morał z tej historii jest dla mnie taki, że jeśli wiem, że nie zmieniłem żadnego kodu, może najpierw powinienem przyjrzeć się konfiguracji VS.
taylorswiftfan
@Lucy Pole wyboru „Użyj 64-bitowej wersji programu IIS Express dla witryn sieci Web i projektów” jest wyłączone
k_kumar
Proszę powiedz Lucy
k_kumar
12

Zwykle może się to zdarzyć, gdy zmienisz docelową strukturę .csproj i powrócisz do tego, od czego zacząłeś.

Upewnij się, że wartość 1, jeśli supportedRuntime version = "inne środowisko uruchomieniowe z celu projektu cs" w tagu startowym w app.config.

Upewnij się, że 2 Oznacza to również sprawdzenie innych plików wygenerowanych automatycznie lub innych plików w folderze Properties, aby sprawdzić, czy nie ma już niezgodności środowiska wykonawczego między tymi plikami a plikami zdefiniowanymi w pliku .csproj.

Może to po prostu zaoszczędzić dużo czasu, zanim zaczniesz próbować różnych rzeczy z właściwościami projektu, aby przezwyciężyć błąd.

purvin
źródło
Natknąłem się na podobny problem i Twoja odpowiedź była dla mnie rozwiązaniem. Mój app.config miał inne obsługiwane środowisko wykonawcze.
Krisztián Kis
9

Miałem ten sam problem, mimo że mam 64-bitowy system Windows 7 i ładowałem 64-bitową bibliotekę DLL b / c we właściwościach projektu | Kompilacja Miałem zaznaczoną opcję „Preferuj 32-bitowe”. (Nie wiem, dlaczego jest to ustawione domyślnie). Gdy to odznaczyłem, wszystko poszło dobrze

SN
źródło
1
To samo tutaj. To załatwiło sprawę. Odwołano się do zestawu 64-bitowego, a konfiguracja aktywnej kompilacji została ustawiona na Dowolny procesor, ale z powodu tego ustawienia „preferuj 32-bitowe” przypuszczalnie użyto 32-bitowego uruchamiania aplikacji i spowodowało problemy.
Bernoulli IT
Wybrano dowolny procesor zamiast x86 w trybie debugowania i działał jak urok.
Cardi DeMonaco Jr
7

Ten wyjątek można również uzyskać, gdy aplikacja jest przeznaczona dla platformy .NET Framework 4.5 (na przykład) i masz następujący plik app.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <startup>
    <supportedRuntime version="v2.0.50727" />
    <supportedRuntime version="v4.0" />
  </startup>
</configuration>

Podczas próby uruchomienia debugowania aplikacji otrzymasz wyjątek BadImageFormatException.

Usunięcie wiersza deklarującego wersję v2.0 spowoduje skasowanie błędu.

Miałem ten problem ostatnio, kiedy próbowałem zmienić platformę docelową ze starego projektu .NET 2.0 na .NET 4.5.

Cédric V
źródło
6

tło

Zaczęliśmy to robić dzisiaj, kiedy zmieniliśmy naszą usługę WCF z AnyCPU na x64 na serwerze Windows 2012 R2 z usługami IIS 6.2.

Najpierw sprawdziliśmy jedyny zestaw, do którego się odwołano, 10 razy, aby upewnić się, że w rzeczywistości nie jest to biblioteka dll x86. Następnie wielokrotnie sprawdzaliśmy pulę aplikacji, aby upewnić się, że nie włącza ona aplikacji 32-bitowych.

Dla kaprysu próbowałem zmienić ustawienie. Okazuje się, że pule aplikacji w usługach IIS miały domyślnie wartość Włącz aplikacje 32-bitowe równą False, ale usługi IIS z jakiegoś powodu ignorowały ją na naszym serwerze i zawsze uruchamiały naszą usługę w trybie x86.

Rozwiązanie

  • Wybierz pulę aplikacji.
  • Wybierz Ustaw domyślne puli aplikacji ... lub Ustawienia zaawansowane ... .
  • Zmień opcję Włącz aplikacje 32-bitowe na True.
  • Kliknij OK .
  • Wybierz domyślne Set Application basenie ... lub Ustawienia zaawansowane ... ponownie.
  • Zmień opcję Włącz aplikacje 32-bitowe z powrotem na Fałsz.
  • Kliknij OK .
JoelC
źródło
4

Rozwiązałem ten problem, zmieniając aplikację internetową tak, aby korzystała z innej „Puli aplikacji”.

Cocu_1012
źródło
4

Dla każdego, kto może tu przyjechać później… Nic nie działało. Wszystkie moje zgromadzenia były w porządku. Miałem konfigurację aplikacji w jednym z moich projektów Visual Studio, której nie powinno tam być. Upewnij się więc, że potrzebny jest plik konfiguracyjny aplikacji.

Usunąłem dodatkową konfigurację aplikacji i zadziałało.

McSick
źródło
Naprawiłem to dla mnie. Mój App.config ustawiał moją aplikację .NET 4.5.1 na 2.0 CLR!
Jared Thirsk
4

Kompilacja docelowa x64 Hosting serwera docelowego IIS 64-bitowy

Jeśli kompilacja aplikacji jest przeznaczona dla 64-bitowego systemu operacyjnego, na 64-bitowym serwerze obsługującym usługi IIS ustaw wartość false dla włączonej aplikacji 32-bitowej w puli aplikacji, w której działa witryna / aplikacja sieci Web.

wprowadź opis obrazu tutaj

VK_217
źródło
2

Określ pulę aplikacji używaną przez aplikację i ustaw właściwość, ustawiając opcję Włącz aplikacje 32-bitowe na wartość Prawda. Można to zrobić za pomocą zaawansowanych ustawień puli aplikacji.

Anand
źródło
2

Podczas tworzenia aplikacji dla platformy 32-bitowej lub 64-bitowej (moje doświadczenie dotyczy programu Visual Studio 2010), nie polegaj na Configuration Manager, aby ustawić odpowiednią platformę dla pliku wykonywalnego. Nawet jeśli CM wybrał x86 dla aplikacji, sprawdź właściwości projektu (zakładka Build): nadal może tam być napisane „Any CPU”. A jeśli uruchomisz plik wykonywalny „Any CPU” na platformie 64-bitowej, będzie on działał w trybie 64-bitowym i odmówi załadowania towarzyszących bibliotek DLL, które zostały utworzone dla platformy x86.

Jeremy Tinkler
źródło
1

Usuń zależność od System.Runtime w swoim Web.Config, zadziałało dla mnie:

<dependentAssembly>
        <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
</dependentAssembly>
Niclas
źródło
Dla mnie to był System.Net.Http. Dzięki za to.
Snickbrack,
1

W przypadku platformy .NET Core występuje błąd programu Visual Studio 2017, który może spowodować, że na stronie kompilacji właściwości projektu będzie wyświetlany niepoprawny cel platformy. Gdy odkryjesz, że problem tkwi, obejścia są dość łatwe. Możesz zmienić cel na inną wartość, a następnie zmienić go z powrotem.

Alternatywnie możesz dodać identyfikator środowiska wykonawczego do pliku .csproj. Jeśli chcesz, aby plik .exe działał jako x86, aby mógł załadować natywną bibliotekę DLL x86, dodaj ten element w PropertyGroup:

<RuntimeIdentifier>win-x86</RuntimeIdentifier>

Dobrym miejscem na umieszczenie tego jest zaraz po elemencie TargetFrameworklub TargetFrameworks.

Edward Brey
źródło
1

Dziwię się, że nikt inny o tym nie wspomniał, więc dzielę się na wypadek, gdyby żadna z powyższych nie pomogła (mój przypadek).

To, co się działo, polegało na tym, że wystąpienie VBCSCompiler.exe w jakiś sposób utknęło i w rzeczywistości nie zwalniało uchwytów plików, aby umożliwić nowym instancjom prawidłowe zapisanie nowych plików i powodowało problem. Stało się to widoczne, gdy próbowałem usunąć folder „bin” i narzekał, że inny proces używa tam plików.

Zamknięto VS, otworzyłem menedżera zadań, przejrzałem i zamknąłem wszystkie instancje VBCSCompiler i usunąłem folder „bin”, aby wrócić do miejsca, w którym byłem.

Źródła: https://developercommunity.visualstudio.com/content/problem/117596/vbcscompilerexe-process-stays-runing-after-exiting.html

Jerzy
źródło
Moim rozwiązaniem było również usunięcie wszystkich katalogów bin i debug.
gabnaim
0

Dla każdego, kto może przyjechać tu później ...
W przypadku rozwiązania Desktop mam BadImageFormatExceptionwyjątek.
Wszystkie opcje kompilacji projektu były w porządku (wszystkie x86). Ale projekt rozwiązania StartUp został zmieniony na inny projekt (projekt biblioteki klas).

W moim przypadku rozwiązaniem była zmiana projektu StartUp na oryginalny (projekt aplikacji .exe)

Fabio
źródło
0

Kiedy napotkałem ten problem, rozwiązały go następujące rozwiązania:

Wołałem bibliotekę dll OpenCV z innego exe, moja dll nie zawierała już potrzebnych bibliotek dll opencv, takich jak highgui, features2d i itp., Dostępnych w folderze mojego pliku exe. Skopiowałem to wszystko do katalogu mojego projektu exe i nagle zadziałało.

Ali Nejad
źródło
0

Ten błąd „Nie można załadować pliku lub zestawu 'przykład' lub jednej z jego zależności. Podjęto próbę załadowania programu o nieprawidłowym formacie” jest zwykle spowodowany nieprawidłową konfiguracją puli aplikacji.

  1. Upewnij się, że pula aplikacji, w której obecnie działa Twoja witryna, ma „Włącz aplikacje 32-bitowe” ustawioną na Fałsz.
  2. Upewnij się, że używasz wersji odpowiedniej dla swojej platformy.
  3. Jeśli otrzymujesz ten błąd w witrynie sieci Web, upewnij się, że pula aplikacji jest ustawiona do działania w odpowiednim trybie (witryny 3.0 powinny działać w trybie 64-bitowym)
  4. Należy również upewnić się, że odwołanie do tego zestawu w programie Visual Studio wskazuje poprawny plik w folderze packages.
  5. Upewnij się, że masz zainstalowaną poprawną wersję biblioteki dll w witrynach GAC dla 2.0.
  6. Może to być również spowodowane promowaniem WSODLibs w projekcie WWW.
Ben Petersen
źródło