Fehlerbehebung bei BadImageFormatException

106

Ich habe einen Windows-Dienst in C # geschrieben, der Visual Studio 2010 verwendet und auf das vollständige .NET Framework 4 abzielt. Wenn ich von einem Debug-Build aus starte, wird der Dienst wie erwartet ausgeführt. Wenn ich es jedoch von einem Release-Build aus starte, erhalte ich eine System.BadImageFormatException (Details unten). Ich habe im Internet nach einer Lösung gesucht, aber bisher hat mir alles, was ich gefunden habe, nicht geholfen, eine Lösung zu finden.

Das Problem besteht sowohl auf Windows 7 64-Bit- (dev) als auch auf Windows XP SP3 32-Bit- (Ziel-) Systemen.

Folgendes habe ich bisher versucht:

  • Verifizierte Build-Einstellungen wie Platform Target sind alle gleich (x86).
  • Wird peverify mit der Option / verbose verwendet, um sicherzustellen, dass die Assembly-Binärdateien gültig sind.
  • Verwendet fuslogvw, um nach Ladeproblemen zu suchen.
  • Verwendet CheckAsm, um nach fehlenden Dateien oder Assembiles zu suchen.

Alle diese Überprüfungen haben nichts geändert. Ich habe den vollständigen Text der Ausnahmeinformationen unten eingefügt, wobei einige der Namen geändert wurden, um die Geheimnisse meiner Unternehmensleiter zu schützen.

System.BadImageFormatException wurde nicht behandelt
  Nachricht = Datei oder Assembly 'XxxDevices, Version = 1.0.0.0, Kultur = neutral, PublicKeyToken = null' oder eine ihrer Abhängigkeiten konnte nicht geladen werden. Es wurde versucht, ein Programm mit einem falschen Format zu laden.
  Source = XxxDevicesService
  Dateiname = XxxDevices, Version = 1.0.0.0, Kultur = neutral, PublicKeyToken = null
  FusionLog = Assembly Manager, geladen aus: C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ clr.dll
Wird unter der ausführbaren Datei c: \ Dev \ TeamE \ bin \ Release \ XxxDevicesService.vshost.exe ausgeführt
--- Es folgt ein detailliertes Fehlerprotokoll. 

=== Statusinformationen vorbinden ===
LOG: Benutzer = XXX
LOG: DisplayName = XxxDevices, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null
 (Vollständig spezifiziert)
LOG: Appbase = Datei: /// c: / Dev / TeamE / bin / Release /
LOG: Initial PrivatePath = NULL
Aufruf der Assembly: XxxDevicesService, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null.
===
LOG: Diese Bindung beginnt im Standardladekontext.
LOG: Verwenden der Anwendungskonfigurationsdatei: c: \ TeamE \ bin \ Release \ XxxDevicesService.vshost.exe.Config
LOG: Verwenden der Host-Konfigurationsdatei: 
LOG: Verwenden der Computerkonfigurationsdatei aus C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ config \ machine.config.
LOG: Die Richtlinie wird derzeit nicht auf Verweise angewendet (private, benutzerdefinierte, teilweise oder standortbasierte Assemblybindung).
LOG: Versuch, eine neue URL-Datei herunterzuladen: /// c: /TeamE/bin/Release/XxxDevices.DLL.
ERR: Fehler beim Abschließen der Montage (hr = 0x8007000b). Die Prüfung wurde beendet.

  StackTrace:
       at XxxDevicesService.Program.Main (String [] args)
       at System.AppDomain._nExecuteAssembly (RuntimeAssembly-Assembly, String [] args)
       bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly ()
       at System.Threading.ExecutionContext.Run (ExecutionContext executeContext, ContextCallback-Rückruf, Objektstatus, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run (ExecutionContext executeContext, ContextCallback-Rückruf, Objektstatus)
       bei System.Threading.ThreadHelper.ThreadStart ()
  InnerException: 

quelle
Mischen Sie überhaupt nativen Code / .net?
Keith Nicholas
1
Sie sind auf dem richtigen Weg, dass diese Ausnahme mit x86 / x64-Bitunterschieden verbunden ist. Ich gehe davon aus, dass dies keine Webanwendung ist, oder? Welche Art der Montage ist das XxxDevicesService? Ist es für eine bestimmte Plattform kompiliert (zB 32 Bit)? Wenn ja, müssen Sie Ihre Plattform auf 32 Bit kompilieren.
Reddog

Antworten:

121

Verifizierte Build-Einstellungen wie Platform Target sind alle gleich (x86).

Das steht nicht im Absturzprotokoll:

Assembly Manager geladen von: C: \ Windows \ Microsoft.NET \ Framework64

Beachten Sie die 64 im Namen, die die Heimat der 64-Bit-Version des Frameworks ist. Legen Sie die Zielplattformeinstellung für Ihr EXE- Projekt fest, nicht für Ihr Klassenbibliotheksprojekt. Das XxxDevicesService EXE-Projekt bestimmt die Bitness des Prozesses.

Hans Passant
quelle
6
Und während Sie das EXE-Projekt überprüfen, überprüfen Sie sowohl Debug als auch Release. : /
Chris
44

Nachdem ich aufgehört habe, meinen Kopf auf den Schreibtisch zu schlagen und an die ganze Woche gedacht habe, in der ich dieses Problem gelöst habe, teile ich mit, was für mich funktioniert hat. Ich habe Win7 64-Bit-, 32-Bit-Oracle-Client und mein MVC 5-Projekt ist aufgrund der Oracle-Bitness so eingestellt, dass es auf einer x86-Plattform ausgeführt wird. Ich bekam immer die gleichen Fehler:

Datei oder Assembly 'Oracle.DataAccess' oder eine ihrer Abhängigkeiten konnte nicht geladen werden. Es wurde versucht, ein Programm mit einem falschen Format zu laden.

Ich habe die NuGet-Pakete neu geladen, Kopien der DLLs verwendet, die für andere in verschiedenen Apps funktionierten. Ich habe die Codebasis in der abhängigen Assembly so festgelegt, dass sie auf den Bin-Ordner meines Projekts verweist. Ich habe CopyLocal als wahr oder falsch ausprobiert . Ich habe alles versucht . Schließlich hatte ich genug getan, um meinen Code einzuchecken, und als neuer Auftragnehmer hatte ich keine Subversion eingerichtet. Während ich nach einer Möglichkeit suchte, es in VS einzubinden, stolperte ich über die Antwort. Ich habe festgestellt, dass die Option "64-Bit-Version von IIS Express für Websites und Projekte verwenden" im Abschnitt "Projekte und Lösungen => Webprojekte" im Menü "Extras => Optionen" deaktiviert ist.

Joey Morgan
quelle
3
Was für ein Lebensretter! Danke dir. Für mich musste ich das tatsächlich überprüfen, da mein Projekt effektiv x64 ist. Danke noch einmal!!!
Viper
Nach all der Hilfe, die ich hier erhalten habe, bin ich sehr froh, einen Teil davon vorwärts zahlen zu können!
Joseph Morgan
3
Stellen Sie für Benutzer von lokalem IIS sicher, dass "32-Bit-Anwendungen aktivieren" Ihres App-Pools (unter Erweiterte Einstellungen) auf " Wahr" gesetzt ist .
Eric Eskildsen
Ein Hinweis auf den obigen Kommentar von @ EricEskildsen zum Thema "32-Bit-Anwendungen aktivieren" im Anwendungspool, auch wenn Sie dies in der Live-Umgebung nicht möchten, kann das Umlegen dieses Schalters zusätzliche Hinweise darauf geben, ob Sie mit einer 32 konfrontiert sind -bit / 64-bit Problem oder etwas anderes.
Ein CVn
Boom! Das war's.
itslittlejohn
21

Ich fand, dass dies funktioniert hat, indem ich die Option "64-Bit-Version von IIS Express für Websites und Projekte verwenden" im Abschnitt "Projekte und Lösungen => Webprojekte" im Menü "Extras => Optionen" aktiviert habe.

Lucy Zhang
quelle
Du bist der Retter. +1
Amit Kumar
Ich habe VS neu installiert und dieses Problem behoben (danke - diese Lösung hat funktioniert). Die Moral der Geschichte lautet für mich: Wenn ich weiß, dass ich zunächst keinen Code geändert habe, sollte ich mir vielleicht zuerst die Konfiguration von VS ansehen.
Taylorswiftfan
@ Lucy Kontrollkästchen "Verwenden Sie die 64-Bit-Version von IIS Express für Websites und Projekte" ist deaktiviert
k_kumar
Bitte sagen Sie Lucy
k_kumar
12

Dies kann normalerweise auftreten, wenn Sie das Zielframework von .csproj geändert und es auf das zurückgesetzt haben, mit dem Sie begonnen haben.

Stellen Sie sicher, dass 1 unter supportRuntime version = "eine andere Laufzeit als das cs-Projektziel" unter dem Start-Tag in app.config angezeigt wird.

Stellen Sie sicher, dass 2 Dies bedeutet auch, dass andere automatisch generierte oder andere Dateien im Eigenschaftenordner überprüft werden, um festzustellen, ob zwischen diesen und einer in der .csproj-Datei definierten Datei keine Laufzeitinkongruenz mehr besteht.

Dies spart Ihnen möglicherweise viel Zeit, bevor Sie verschiedene Dinge mit Projekteigenschaften ausprobieren, um den Fehler zu beheben.

Purvin
quelle
Ich bin auf ein ähnliches Problem gestoßen, und Ihre Antwort war die Lösung für mein Problem. Meine app.config hatte eine andere unterstützte Laufzeit.
Krisztián Kis
9

Ich hatte das gleiche Problem, obwohl ich 64-Bit-Windows 7 habe und eine 64-Bit-DLL b / c in den Projekteigenschaften | geladen habe Build Ich hatte "32-Bit bevorzugen" aktiviert. (Weiß nicht, warum das standardmäßig eingestellt ist). Sobald ich das deaktiviert hatte, lief alles gut

SN
quelle
1
Hier gilt das gleiche. Das hat den Trick gemacht. Es wurde auf eine 64-Bit-Assembly verwiesen, und die aktive Build-Konfiguration wurde auf Beliebige CPU festgelegt. Aufgrund dieser Einstellung "32-Bit bevorzugen" wurde vermutlich 32-Bit verwendet, um die Anwendung auszuführen und die Probleme zu verursachen.
Bernoulli IT
Picked Jede CPU statt x86 in Debug - Modus und arbeitete wie ein Charme.
Cardi DeMonaco Jr
7

Sie können diese Ausnahme auch erhalten, wenn Ihr Anwendungsziel (z. B.) .NET Framework 4.5 ist und Sie die folgende app.config haben:

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

Wenn Sie versuchen, das Debugging der Anwendung zu starten, erhalten Sie die BadImageFormatException.

Durch Entfernen der Zeile, in der die Version 2.0 deklariert ist, wird der Fehler behoben.

Ich hatte dieses Problem kürzlich, als ich versuchte, die Zielplattform von einem alten .NET 2.0-Projekt auf .NET 4.5 zu ändern.

Cédric V.
quelle
6

Hintergrund

Wir haben heute damit begonnen, als wir unseren WCF-Dienst auf einem Windows 2012 R2-Server mit IIS 6.2 von AnyCPU auf x64 umgestellt haben.

Zuerst haben wir die einzige Assembly, auf die verwiesen wird, zehnmal überprüft, um sicherzustellen, dass es sich nicht um eine x86-DLL handelt. Als Nächstes haben wir den Anwendungspool viele Male überprüft, um sicherzustellen, dass keine 32-Bit-Anwendungen aktiviert wurden.

Aus einer Laune heraus habe ich versucht, die Einstellung umzuschalten. Es stellte sich heraus, dass die Anwendungspools in IIS standardmäßig den Wert " 32-Bit-Anwendungen aktivieren" von "Falsch" verwendeten, aber IIS ignorierte ihn aus irgendeinem Grund auf unserem Server und führte unseren Dienst immer im x86-Modus aus.

Lösung

  • Wählen Sie den App-Pool aus.
  • Wählen Sie Set Application Pool Defaults ... oder Erweiterte Einstellungen ... .
  • Ändern Sie " 32-Bit-Anwendungen aktivieren" in "Wahr".
  • Klicken Sie auf OK .
  • Wählen Sie erneut Set Pool Defaults festlegen oder Advanced Settings .
  • Ändern Sie " 32-Bit-Anwendungen aktivieren" wieder in "Falsch".
  • Klicken Sie auf OK .
JoelC
quelle
4

Ich habe dieses Problem behoben, indem ich die Webanwendung so geändert habe, dass sie einen anderen "Anwendungspool" verwendet.

Cocu_1012
quelle
4

Für alle, die zu einem späteren Zeitpunkt hier ankommen könnten ... Für mich hat nichts funktioniert. Alle meine Versammlungen waren in Ordnung. Ich hatte eine App-Konfiguration in einem meiner Visual Studio-Projekte, die nicht dort hätte sein dürfen. Stellen Sie also sicher, dass Ihre App-Konfigurationsdatei benötigt wird.

Ich habe die zusätzliche App-Konfiguration gelöscht und es hat funktioniert.

McSick
quelle
Es wurde für mich behoben. Meine App.config hat meine .NET 4.5.1-App auf die 2.0 CLR eingestellt!
Jared Thirsk
4

Zielerstellung x64 Zielserver Hosting IIS 64 Bit

Wenn der Anwendungsaufbau auf ein 64-Bit-Betriebssystem abzielt, setzen Sie auf dem 64-Bit-Server, auf dem sich der IIS befindet, die 32-Bit-Aktivierungsanwendung im App-Pool, auf dem die Website / Webanwendung ausgeführt wird, auf false.

Geben Sie hier die Bildbeschreibung ein

VK_217
quelle
2

Bestimmen Sie den von der Anwendung verwendeten Anwendungspool und legen Sie die Eigenschaft von fest, indem Sie 32-Bit-Anwendungen aktivieren auf True setzen. Dies kann durch erweiterte Einstellungen des Anwendungspools erfolgen.

Anand
quelle
2

Verlassen Sie sich beim Erstellen von Apps für die 32-Bit- oder 64-Bit-Plattform (nach meiner Erfahrung mit Visual Studio 2010) nicht auf den Konfigurationsmanager, um die richtige Plattform für die ausführbare Datei festzulegen. Selbst wenn auf dem CM x86 für die Anwendung ausgewählt ist, überprüfen Sie die Projekteigenschaften (Registerkarte Erstellen): Dort wird möglicherweise immer noch "Beliebige CPU" angezeigt. Wenn Sie eine ausführbare Datei "Beliebige CPU" auf einer 64-Bit-Plattform ausführen, wird sie im 64-Bit-Modus ausgeführt und lehnt das Laden der zugehörigen DLLs ab, die für die x86-Plattform erstellt wurden.

Jeremy Tinkler
quelle
1

Entfernen Sie Ihre Abhängigkeit von System.Runtime in Ihrer Web.Config, es hat bei mir funktioniert:

<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
quelle
Für mich war es das System.Net.Http. Danke dafür.
Snickbrack
1

Für .NET Core gibt es einen Visual Studio 2017-Fehler , der dazu führen kann, dass auf der Seite "Projekteigenschaften erstellen" das falsche Plattformziel angezeigt wird. Sobald Sie feststellen, dass das Problem vorliegt, sind die Problemumgehungen ziemlich einfach. Sie können das Ziel in einen anderen Wert ändern und dann wieder ändern.

Alternativ können Sie der .csproj eine Laufzeitkennung hinzufügen. Wenn Ihre EXE-Datei als x86 ausgeführt werden soll, damit eine native x86-DLL geladen werden kann, fügen Sie dieses Element in Folgendes ein PropertyGroup:

<RuntimeIdentifier>win-x86</RuntimeIdentifier>

Ein guter Ort, um dies zu setzen, ist direkt nach dem TargetFrameworkoder TargetFrameworksElement.

Edward Brey
quelle
1

Ich bin überrascht, dass niemand anderes dies erwähnt hat, also teile ich für den Fall, dass keine der oben genannten Hilfen (mein Fall).

Was passierte war, dass eine VBCSCompiler.exe-Instanz irgendwie feststeckte und tatsächlich die Dateihandles nicht freigab, damit neue Instanzen die neuen Dateien korrekt schreiben konnten, und das Problem verursachte. Dies wurde deutlich, als ich versuchte, den Ordner "bin" zu löschen, und es wurde beanstandet, dass ein anderer Prozess dort Dateien verwendete.

VS geschlossen, Task-Manager geöffnet, alle VBCSCompiler-Instanzen gesucht und beendet und den Ordner "bin" gelöscht, um zu meinem Standort zurückzukehren.

Referenz: https://developercommunity.visualstudio.com/content/problem/117596/vbcscompilerexe-process-stays-runing-after-exiting.html

George
quelle
Meine Lösung bestand auch darin, alle bin- und Debug-Verzeichnisse zu löschen.
Gabnaim
0

Für alle, die zu einem späteren Zeitpunkt hier ankommen könnten ...
Für die Desktop-Lösung habe ich eine BadImageFormatExceptionAusnahme erhalten.
Alle Build-Optionen des Projekts waren in Ordnung (allex86 ). Das StartUp-Lösungsprojekt wurde jedoch in ein anderes Projekt (Klassenbibliotheksprojekt) geändert.

Das Ändern des StartUp-Projekts in das Original (.exe-Anwendungsprojekt) war in meinem Fall eine Lösung

Fabio
quelle
0

Als ich mit diesem Problem konfrontiert wurde, löste es Folgendes für mich:

Ich habe eine OpenCV-DLL aus einer anderen Exe heraus aufgerufen. Meine DLL enthielt nicht die bereits benötigten OpenCV-DLLs wie Highgui, Features2d usw., die im Ordner meiner Exe-Datei verfügbar sind. Ich habe all dies in das Verzeichnis meines exe-Projekts kopiert und es hat plötzlich funktioniert.

Ali Nejad
quelle
0

Dieser Fehler "Datei- oder Assembly-Beispiel 'oder eine ihrer Abhängigkeiten konnte nicht geladen werden. Es wurde versucht, ein Programm mit einem falschen Format zu laden" wird normalerweise durch eine falsche Konfiguration des Anwendungspools verursacht.

  1. Stellen Sie sicher, dass für den AppPool, auf dem Ihre Site derzeit ausgeführt wird, "32-Bit-Anwendungen aktivieren" auf "Falsch" gesetzt ist.
  2. Stellen Sie sicher, dass Sie die richtige Version für Ihre Plattform verwenden.
  3. Wenn dieser Fehler auf einer Website angezeigt wird, stellen Sie sicher, dass Ihr Anwendungspool so eingestellt ist, dass er im richtigen Modus ausgeführt wird (3.0-Websites sollten im 64-Bit-Modus ausgeführt werden).
  4. Sie sollten auch sicherstellen, dass der Verweis auf diese Assembly in Visual Studio auf die richtige Datei im Paketordner verweist.
  5. Stellen Sie sicher, dass Sie die richtige Version der DLL im GAC für 2.0-Sites installiert haben.
  6. Dies kann auch dadurch verursacht werden, dass WSODLibs mit dem Webprojekt hochgestuft werden.
Ben Petersen
quelle