Risoluzione dei problemi di BadImageFormatException

Ho un servizio di Windows scritto in C # utilizzando Visual Studio 2010 e il targeting completo di .NET Framework 4. Quando esco da una build di debug il servizio viene eseguito come previsto. Tuttavia, quando lo eseguo da una build di rilascio ottengo un System.BadImageFormatException (dettagli sotto). Ho cercato su internet una soluzione, ma finora tutte le cose che ho trovato non mi hanno 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 (destinazione).

Ecco cosa ho provato finora:

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

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

 System.BadImageFormatException was nothanded Message = Imansible 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.  Source = XxxDevicesService FileName = XxxDevices, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null FusionLog = Assembly manager caricato da: C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ clr.dll Esecuzione sotto eseguibile c: \ Dev \ TeamE \ bin \ Release \ XxxDevicesService.vshost.exe --- Segue un registro degli errori dettagliato.  === Informazioni sullo stato precedente alla registrazione === LOG: Utente = XXX LOG: DisplayName = XxxDevices, Versione = 1.0.0.0, Culture = neutral, PublicKeyToken = null (Completamente specificato) LOG: Appbase = file: /// c : / Dev / TeamE / bin / Release / LOG: Initial PrivatePath = NULL Assegnazione chiamata: XxxDevicesService, Versione = 1.0.0.0, Culture = neutral, PublicKeyToken = null.  === LOG: questo bind 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 macchina da C: \ Windows \ Microsoft.NET \ Framework64 \ v4. 0,30,319 mila \ config \ machine.config.  LOG: la politica non viene applicata al riferimento in questo momento (binding dell'assieme privato, personalizzato, parziale o basato sulla posizione).  LOG: Tentativo di scaricare il nuovo file URL: /// c: /TeamE/bin/Release/XxxDevices.DLL.  ERR: imansible completare l'installazione dell'assembly (hr = 0x8007000b).  Probing terminato.  StackTrace: at XxxDevicesService.Program.Main (String [] args) in System.AppDomain._nExecuteAssembly (assembly RuntimeAssembly, String [] args) in Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly () in System.Threading.ExecutionContext.Run ( ExecutionContext executionContext, callback ContextCallback, stato dell'object, booleano ignoreSyncCtx) in System.Threading.ExecutionContext.Run (ExecutionContext executionContext, callback ContextCallback, stato Object) in System.Threading.ThreadHelper.ThreadStart () InnerException: 

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

Non è quello che dice il registro di crash:

Assembly manager caricato da: C: \ Windows \ Microsoft.NET \ Framework64

Notare il 64 nel nome, che è la sede della versione a 64 bit del framework. Impostare l’impostazione della piattaforma di destinazione sul progetto EXE , non sul progetto della libreria di classi. Il progetto EXE XxxDevicesService determina il testimone del processo.

Dopo che ho smesso di sbattere la testa sulla scrivania pensando a tutta la settimana che ho passato a scovare questo problema, sto condividendo ciò che ha funzionato per me. Ho Win7 64 bit, client Oracle a 32 bit, e ho il mio progetto MVC 5 impostato per funzionare su piattaforma x86 a causa del testimone di Oracle. Ho continuato a ricevere gli stessi errori:

Imansible 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 hanno funzionato per gli altri in diverse app, ho impostato il codice nell’assembly dipendente per puntare alla cartella bin del mio progetto, ho provato CopyLocal come vero o falso, ho provato di tutto. Finalmente avevo fatto abbastanza altro da voler controllare il mio codice e, come nuovo appaltatore, non avevo impostato la sovversione. Mentre cercavo un modo per agganciarlo a VS, sono inciampato nella risposta. Quello che ho trovato funzionante è stato deselezionare l’opzione “Usa la versione a 64 bit di IIS Express per siti Web e progetti” sotto la sezione Progetti e soluzioni => Progetti Web sotto il menu Strumenti => Opzioni.

Quello che ho trovato ha funzionato è stato il controllo dell’opzione “Usa la versione a 64 bit di IIS Express per siti Web e progetti” sotto la sezione Progetti e soluzioni => Progetti Web sotto il menu Strumenti => Opzioni.

In genere può verificarsi quando hai modificato il framework di destinazione di .csproj e lo hai ripristinato a ciò che hai iniziato.

Assicurati che 1 se supportato Versione runtime = “un runtime diverso dalla destinazione del progetto cs” sotto tag di avvio in app.config.

Assicurati che 2 Significa anche controllare altri file autogenerati o altri file nella cartella delle proprietà per vedere se non c’è più disallineamento di runtime tra questi file e uno che è definito nel file .csproj.

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

Ho avuto lo stesso problema anche se ho Windows 7 a 64 bit e stavo caricando un DLL b / c a 64 bit nelle proprietà del progetto | Build I aveva “Preferisci 32 bit” controllato. (Non so perché è impostato di default). Una volta deselezionata, tutto è andato per il meglio

È inoltre ansible ottenere questa eccezione quando l’applicazione è impostata su .NET Framework 4.5 (ad esempio) e si dispone della seguente app.config:

 < ?xml version="1.0" encoding="utf-8"?>       

Quando provi ad avviare il debug dell’applicazione otterrai la BadImageFormatException.

La rimozione della riga che dichiara la versione 2.0 eliminerà 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.

sfondo

Abbiamo iniziato a farlo 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 l’unico assembly di riferimento 10 volte, per assicurarsi che non fosse effettivamente una DLL x86. Successivamente abbiamo controllato il pool di applicazioni più volte per garantire che non abilitasse applicazioni a 32 bit.

Per un capriccio ho provato a cambiare l’impostazione. Risulta che i pool di applicazioni in IIS erano predefiniti a un valore Abilita applicazioni a 32 bit di False, ma IIS lo ignorava sul nostro server per qualche motivo e eseguiva sempre il nostro servizio in modalità x86.

Soluzione

  • Seleziona il pool di app.
  • Scegli Imposta impostazioni predefinite pool di applicazioni … o Impostazioni avanzate ….
  • Cambia Abilita applicazioni a 32 bit su True.
  • Clicca OK .
  • Scegliere Imposta impostazioni predefinite pool di applicazione … o Impostazioni avanzate … nuovamente.
  • Cambia Abilita applicazioni a 32 bit su False.
  • Clicca OK .

Ho risolto questo problema modificando l’app Web per utilizzare un diverso “pool di applicazioni”.

Per chiunque possa arrivare qui in un secondo momento …. Niente ha funzionato per me. Tutte le mie assemblee andavano bene. Ho avuto una configurazione dell’app in uno dei miei progetti di Visual Studio che non avrebbe dovuto essere lì. Quindi assicurati che il tuo file di configurazione dell’app sia necessario.

Ho eliminato la configurazione aggiuntiva dell’app e ha funzionato.

Determinare il pool di applicazioni utilizzato dall’applicazione e impostare la proprietà di impostando Abilita applicazioni a 32 bit su True. Questo può essere fatto attraverso le impostazioni avanzate del pool di applicazioni.

Quando si creano app per piattaforms 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 Crea): potrebbe ancora dire “Qualsiasi CPU” lì. E se si esegue un eseguibile “Qualsiasi 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.

Per chiunque possa arrivare qui in un secondo momento …
Per la soluzione Desktop ho ottenuto BadImageFormatException eccezione BadImageFormatException .
Tutte le opzioni di costruzione del progetto andavano bene (tutte x86 ). Ma il progetto StartUp di soluzione è stato cambiato in qualche altro progetto (progetto di libreria di classi).

Cambiare il progetto di avvio nell’originale (progetto di applicazione .exe) era una soluzione nel mio caso

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

Stavo chiamando una DLL OpenCV da un altro exe, la mia DLL non conteneva le dll opencv già necessarie come highgui, features2d ed ecc disponibili nella cartella del mio file exe. Ho copiato tutti questi file nella directory del mio progetto exe e improvvisamente ha funzionato.

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

     

Questo errore “Imansible caricare l’esempio di file o assembly” o una delle sue dipendenze. È stato effettuato un tentativo di caricare un programma con un formato errato “in genere causato da una configurazione errata del pool di applicazioni.

  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 si verifica questo errore su un sito Web, assicurarsi che il pool di applicazioni sia impostato per l’esecuzione nella modalità corretta (i siti 3.0 devono essere eseguiti in modalità 64 bit)
  4. Dovresti anche assicurarti che il riferimento a quell’assembly in visual studio indichi il file corretto nella cartella packages.
  5. Assicurarsi di disporre della versione corretta della dll installata nel GAC per i siti 2.0.
  6. Ciò può anche essere causato da WSODLibs promosso con il progetto web.

Per .NET Core , esiste un bug di Visual Studio 2017 che può causare la pagina di generazione delle proprietà del progetto per mostrare la destinazione della piattaforma errata. Una volta scoperto che il problema è, i workaround sono piuttosto semplici. È ansible modificare l’objective su un altro valore e quindi modificarlo.

In alternativa, è ansible aggiungere un identificatore di runtime a .csproj. Se hai bisogno che il tuo .exe sia eseguito come x86 in modo che possa caricare una DLL nativa x86, aggiungi questo elemento all’interno di un PropertyGroup :

 win-x86 

Un buon posto per mettere questo è giusto dopo l’elemento TargetFramework o TargetFrameworks .