Risoluzione dei problemi di BadImageFormatException


107

Ho un servizio Windows scritto in C # che utilizza Visual Studio 2010 e mira a .NET Framework 4. Quando eseguo da una build di debug, il servizio viene eseguito come previsto. Tuttavia, quando lo eseguo da una build di rilascio ottengo un'eccezione System.BadImageFormatException (dettagli di seguito). Ho cercato una soluzione su Internet, ma finora tutto ciò che ho trovato non mi ha aiutato a trovare una soluzione.

Il problema esiste su entrambi i sistemi Windows 7 a 64 bit (dev) e Windows XP SP3 a 32 bit (di destinazione).

Ecco cosa ho provato finora:

  • Le impostazioni di build verificate come Platform Target sono tutte uguali (x86).
  • Ha usato peverify con l'opzione / verbose per assicurarsi che i file binari dell'assembly fossero validi.
  • Utilizza fuslogvw per cercare eventuali problemi di caricamento.
  • Ha utilizzato CheckAsm per cercare file mancanti o assembly.

Tutti questi controlli non hanno cambiato nulla. Ho incluso il testo completo delle informazioni sull'eccezione di seguito, con alcuni dei nomi modificati per proteggere i segreti dei miei dirigenti aziendali.

System.BadImageFormatException non è stato gestito
  Messaggio = Impossibile caricare il file o l'assembly "XxxDevices, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null" o una delle sue dipendenze. Si è tentato di caricare un programma con un formato errato.
  Fonte = XxxDevicesService
  FileName = XxxDevices, versione = 1.0.0.0, Culture = neutral, PublicKeyToken = null
  FusionLog = Assembly manager caricato da: C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ clr.dll
In esecuzione nell'eseguibile c: \ Dev \ TeamE \ bin \ Release \ XxxDevicesService.vshost.exe
--- Segue un registro dettagliato degli errori. 

=== Informazioni sullo stato pre-binding ===
LOG: Utente = XXX
LOG: DisplayName = XxxDevices, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null
 (Fully-specificato)
LOG: Appbase = file: /// c: / Dev / TeamE / bin / Release /
LOG: Initial PrivatePath = NULL
Chiamata all'assembly: XxxDevicesService, versione = 1.0.0.0, Culture = neutral, PublicKeyToken = null.
===
LOG: questo collegamento inizia nel contesto di caricamento predefinito.
LOG: utilizzando il file di configurazione dell'applicazione: c: \ TeamE \ bin \ Release \ XxxDevicesService.vshost.exe.Config
LOG: utilizzando il file di configurazione host: 
LOG: utilizzando il file di configurazione della macchina da C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ config \ machine.config.
LOG: criterio non applicato al riferimento in questo momento (binding di assembly privato, personalizzato, parziale o basato sulla posizione).
LOG: Tentativo di download del nuovo file URL: /// c: /TeamE/bin/Release/XxxDevices.DLL.
ERR: impossibile completare la configurazione dell'assembly (hr = 0x8007000b). Sondaggio terminato.

  StackTrace:
       in XxxDevicesService.Program.Main (String [] args)
       in System.AppDomain._nExecuteAssembly (assembly RuntimeAssembly, String [] args)
       presso Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly ()
       in System.Threading.ExecutionContext.Run (ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       in System.Threading.ExecutionContext.Run (ExecutionContext executionContext, ContextCallback callback, Object state)
       in System.Threading.ThreadHelper.ThreadStart ()
  InnerException: 
c#  .net  exception 

stai mescolando codice nativo / .net?
Keith Nicholas

1
Sei sulla buona strada che questa eccezione è associata a differenze di bit x86 / x64. Presumo che questa non sia un'applicazione web, giusto? Inoltre, che tipo di assemblaggio è XxxDevicesService? È compilato per una piattaforma specifica (es. 32 bit)? In tal caso, è necessario compilare la piattaforma a 32 bit.
Reddog

Risposte:


121

Le impostazioni di build verificate come Platform Target sono tutte uguali (x86).

Non è quello che dice il registro dei crash:

Gestore assembly caricato da: C: \ Windows \ Microsoft.NET \ Framework64

Nota il 64 nel nome, che è la casa della versione a 64 bit del framework. Impostare l'impostazione della piattaforma di destinazione nel progetto EXE , non nel progetto della libreria di classi. Il progetto EXE XxxDevicesService determina il bitness del processo.


6
E mentre stai controllando il progetto EXE, controlla sia Debug che Release. : /
chris

44

Dopo aver smesso di sbattere la testa sulla scrivania pensando all'intera settimana che ho passato a risolvere questo problema, condivido ciò che ha funzionato per me. Ho Win7 64 bit, client Oracle a 32 bit e il mio progetto MVC 5 è impostato per essere eseguito su piattaforma x86 a causa di Oracle bitness. Continuavo a ricevere gli stessi errori:

Impossibile caricare il file o l'assembly "Oracle.DataAccess" o una delle sue dipendenze. Si è tentato di caricare un programma con un formato errato.

Ho ricaricato i pacchetti NuGet, ho usato copie delle DLL che funzionavano per altri in diverse app, ho impostato il codebase nell'assembly dipendente in modo che punti alla cartella bin del mio progetto, ho provato CopyLocal come true o false, ho provato di tutto. Finalmente ho fatto abbastanza altro volevo controllare il mio codice e, come nuovo appaltatore, non avevo configurato sovversione. Mentre cercavo un modo per collegarlo a VS, sono inciampato nella risposta. Quello che ho trovato ha funzionato è stato deselezionare l'opzione "Usa la versione a 64 bit di IIS Express per siti Web e progetti" nella sezione Progetti e soluzioni => Progetti Web nel menu Strumenti => Opzioni.


3
Che salvavita !! Grazie. Per me ho dovuto verificarlo, poiché il mio progetto è effettivamente x64. Grazie ancora!!!
Viper

Dopo tutto l'aiuto che ho ricevuto qui, sono molto contento di aver potuto pagarne una parte in avanti!
Joseph Morgan

3
Per coloro che utilizzano IIS locale, assicurati che "Abilita applicazioni a 32 bit" del tuo pool di app (in Impostazioni avanzate) sia impostato su True .
Eric Eskildsen

Un addenum al commento di @ EricEskildsen sopra su "abilitare le applicazioni a 32 bit" nel pool di applicazioni, anche se non vuoi farlo nell'ambiente live, capovolgere quell'interruttore può fornire ulteriori indizi sul fatto che tu stia affrontando un 32 -bit / 64-bit problema o qualcos'altro.
un CVn

Boom! Questo è tutto.
itslittlejohn

21

Quello che ho trovato funzionava è stato controllare l'opzione "Usa la versione a 64 bit di IIS Express per siti Web e progetti" nella sezione Progetti e soluzioni => Progetti Web nel menu Strumenti => Opzioni.


tu sei il salvatore. +1
Amit Kumar

Ho reinstallato VS e stavo risolvendo questo problema (grazie - questa soluzione ha funzionato). La morale della storia per me è che se so di non aver cambiato alcun codice per cominciare, forse dovrei prima guardare la configurazione di VS.
taylorswiftfan

La casella di controllo @Lucy "Usa la versione a 64 bit di IIS Express per siti Web e progetti" è disattivata
disattivata k_kumar

Per favore dillo a Lucy
k_kumar

12

In genere può verificarsi quando si modifica il framework di destinazione di .csproj e lo si ripristina con quello con cui si è iniziato.

Assicurati 1 se supportedRuntime version = "a different runtime from cs project target" sotto il tag di avvio in app.config.

Assicurati 2 Ciò significa anche controllare altri file generati automaticamente o altri file nella cartella delle proprietà per vedere se non ci sono più mancate corrispondenze di runtime tra questi file e uno definito nel file .csproj.

Questi potrebbero farti risparmiare molto tempo prima di iniziare a provare cose diverse con le proprietà del progetto per superare l'errore.


Mi sono imbattuto in un problema simile e la tua risposta è stata la soluzione per la mia. Il mio app.config aveva un runtime supportato diverso.
Krisztián Kis

9

Ho avuto lo stesso problema anche se ho Windows 7 a 64 bit e stavo caricando una DLL a 64 bit b / c nelle proprietà del progetto | Build Ho controllato "Prefer 32-bit". (Non so perché è impostato di default). Una volta deselezionato, è andato tutto bene


1
Anch'io. Questo ha funzionato. Ha fatto riferimento a un assembly a 64 bit e la configurazione della build attiva è stata impostata su Qualsiasi CPU, ma a causa di questa impostazione "preferisci 32 bit" presumibilmente a 32 bit è stato utilizzato per eseguire l'applicazione e ha causato i problemi.
Bernoulli IT

Ha scelto qualsiasi CPU invece di x86 in modalità di debug e ha funzionato a meraviglia.
Cardi DeMonaco Jr

7

Puoi anche ottenere questa eccezione quando la tua applicazione ha come destinazione .NET Framework 4.5 (ad esempio) e hai il seguente app.config:

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

Quando si tenta di avviare il debug dell'applicazione, verrà visualizzata l'eccezione BadImageFormatException.

La rimozione della riga che dichiara la versione v2.0 cancellerà l'errore.

Ho avuto questo problema di recente quando ho provato a cambiare la piattaforma di destinazione da un vecchio progetto .NET 2.0 a .NET 4.5.


6

sfondo

Abbiamo iniziato a ottenerlo oggi quando abbiamo cambiato il nostro servizio WCF da AnyCPU a x64 su un server Windows 2012 R2 con IIS 6.2.

Per prima cosa abbiamo controllato 10 volte l'unico assembly a cui si fa riferimento, per assicurarci che non fosse effettivamente una dll x86. Successivamente abbiamo controllato più volte il pool di applicazioni per assicurarci che non abilitasse applicazioni a 32 bit.

Per un capriccio ho provato a cambiare l'impostazione. Risulta che i pool di applicazioni in IIS utilizzavano per impostazione predefinita un file Abilita applicazioni a 32 bit False, ma IIS lo ignorava sul nostro server per qualche motivo e ha sempre eseguito il nostro servizio in modalità x86.

Soluzione

  • Seleziona il pool di app.
  • Scegliere Imposta valori predefiniti pool di applicazioni ... o Impostazioni avanzate ... .
  • Modifica Abilita applicazioni a 32 bit a su True.
  • Fare clic su OK .
  • Scegliere Imposta valori predefiniti pool di applicazioni ... o Impostazioni avanzate ... di nuovo.
  • Modifica Abilita applicazioni a 32 bit su False.
  • Fare clic su OK .

4

Ho risolto questo problema modificando l'app Web per utilizzare un "pool di applicazioni" diverso.


4

Per chiunque possa arrivare qui in un secondo momento ... Niente ha funzionato per me. Tutte le mie assemblee andavano bene. Avevo una configurazione dell'app in uno dei miei progetti di Visual Studio che non avrebbe dovuto esserci. Quindi assicurati che il file di configurazione dell'app sia necessario.

Ho eliminato la configurazione dell'app extra e ha funzionato.


Risolto il problema per me. Il mio App.config stava impostando la mia app .NET 4.5.1 su 2.0 CLR!
Jared Thirsk

4

Target build x64 Server di destinazione che ospita IIS 64 bit

Se la build dell'applicazione è destinata al sistema operativo a 64 bit, quindi sul server a 64 bit che ospita IIS, impostare su false l'abilitazione dell'applicazione a 32 bit nel pool di app che esegue il sito Web / applicazione Web.

inserisci qui la descrizione dell'immagine


2

Determinare il pool di applicazioni utilizzato dall'applicazione e impostare la proprietà di impostando Abilita applicazioni a 32 bit su True. Questa operazione può essere eseguita tramite le impostazioni avanzate del pool di applicazioni.


2

Quando si creano app per la piattaforma a 32 o 64 bit (la mia esperienza è con Visual Studio 2010), non fare affidamento su Configuration Manager per impostare la piattaforma corretta per l'eseguibile. Anche se il CM ha selezionato x86 per l'applicazione, controlla le proprietà del progetto (scheda Build): potrebbe ancora dire "Any CPU". E se esegui un eseguibile "Any CPU" su una piattaforma a 64 bit, verrà eseguito in modalità a 64 bit e si rifiuterà di caricare le DLL di accompagnamento create per la piattaforma x86.


1

Rimuovi la tua dipendenza da System.Runtime nel tuo Web.Config, ha funzionato per me:

<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>

Per me è stato il System.Net.Http. Grazie per questo.
Snickbrack

1

Per .NET Core , esiste un bug di Visual Studio 2017 che può far sì che la pagina Build delle proprietà del progetto mostri la destinazione della piattaforma non corretta. Una volta scoperto che il problema è, le soluzioni alternative sono piuttosto semplici. È possibile modificare l'obiettivo con un altro valore e quindi modificarlo nuovamente.

In alternativa, puoi aggiungere un identificatore di runtime al file .csproj. Se hai bisogno che il tuo .exe venga eseguito come x86 in modo che possa caricare una DLL nativa x86, aggiungi questo elemento all'interno di PropertyGroup:

<RuntimeIdentifier>win-x86</RuntimeIdentifier>

Un buon posto per metterlo è subito dopo l' elemento TargetFrameworko TargetFrameworks.


1

Sono sorpreso che nessun altro lo abbia menzionato, quindi condivido nel caso in cui nessuno dei suddetti aiuti (il mio caso).

Quello che stava succedendo era che un'istanza di VBCSCompiler.exe era in qualche modo bloccata e di fatto non stava rilasciando gli handle di file per consentire alle nuove istanze di scrivere correttamente i nuovi file e stava causando il problema. Ciò è diventato evidente quando ho provato a eliminare la cartella "bin" e si lamentava che un altro processo stava usando i file lì dentro.

VS chiuso, task manager aperto, ha esaminato e terminato tutte le istanze di VBCSCompiler ed eliminato la cartella "bin" per tornare al punto in cui mi trovavo.

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


La mia soluzione era anche quella di eliminare tutte le directory bin e di debug.
gabnaim

0

Per chiunque possa arrivare qui in un secondo momento ...
Per la soluzione Desktop ho ottenuto BadImageFormatExceptionun'eccezione.
Tutte le opzioni di compilazione del progetto andavano bene (tuttix86 ). Ma il progetto di soluzione StartUp è stato modificato in un altro progetto (progetto di libreria di classi).

La modifica del progetto StartUp nell'originale (progetto dell'applicazione .exe) è stata una soluzione nel mio caso


0

Quando ho affrontato questo problema, il seguente lo ha risolto per me:

Stavo chiamando una dll OpenCV dall'interno di un altro exe, la mia dll non conteneva le dll opencv già necessarie come highgui, features2d e così via disponibili nella cartella del mio file exe. Ho copiato tutti questi nella directory del mio progetto exe e improvvisamente ha funzionato.


0

Questo errore "Impossibile caricare il file o l'assembly" esempio "o una delle sue dipendenze. È stato effettuato un tentativo di caricare un programma con un formato errato" in genere è causato da una configurazione del pool di applicazioni errata.

  1. Assicurati che l'AppPool su cui è attualmente in esecuzione il tuo sito abbia "Abilita applicazioni a 32 bit" impostato su False.
  2. Assicurati di utilizzare la versione corretta per la tua piattaforma.
  3. Se ricevi questo errore su un sito web, assicurati che il tuo pool di applicazioni sia impostato per essere eseguito nella modalità corretta (i siti 3.0 dovrebbero essere eseguiti in modalità a 64 bit)
  4. È inoltre necessario assicurarsi che il riferimento a quell'assembly in Visual Studio punti al file corretto nella cartella dei pacchetti.
  5. Assicurati di avere la versione corretta della dll installata nella GAC ​​per i siti 2.0.
  6. Ciò può anche essere causato dalla promozione di WSODLibs con il progetto web.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.