Solución de problemas de BadImageFormatException

107

Tengo un servicio de Windows escrito en C # usando Visual Studio 2010 y dirigido a .NET Framework 4. Cuando ejecuto desde una compilación de depuración, el servicio se ejecuta como se esperaba. Sin embargo, cuando lo ejecuto desde una versión de versión, obtengo una System.BadImageFormatException (detalles a continuación). He estado buscando una solución en Internet, pero hasta ahora todo lo que he encontrado no me ha ayudado a encontrar una solución.

El problema existe en los sistemas Windows 7 de 64 bits (dev) y Windows XP SP3 de 32 bits (destino).

Esto es lo que he probado hasta ahora:

  • Las configuraciones de compilación verificadas, como Platform Target, son todas iguales (x86).
  • Se usa peverify con la opción / verbose para garantizar que los binarios del ensamblado sean válidos.
  • Utiliza fuslogvw para buscar problemas de carga.
  • Utiliza CheckAsm para buscar archivos o ensamblados faltantes.

Todos estos controles no cambiaron nada. Incluí el texto completo de la información de la excepción a continuación, con algunos de los nombres cambiados para proteger los secretos de mis maestros corporativos.

System.BadImageFormatException no se controló
  Mensaje = No se pudo cargar el archivo o ensamblado 'XxxDevices, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null' o una de sus dependencias. Se intentó cargar un programa con un formato incorrecto.
  Fuente = XxxDevicesService
  FileName = XxxDevices, Versión = 1.0.0.0, Cultura = neutral, PublicKeyToken = nulo
  FusionLog = Administrador de ensamblaje cargado desde: C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ clr.dll
Ejecutando en ejecutable c: \ Dev \ TeamE \ bin \ Release \ XxxDevicesService.vshost.exe
--- A continuación se muestra un registro de errores detallado. 

=== Información de estado previa al enlace ===
REGISTRO: Usuario = XXX
REGISTRO: DisplayName = XxxDevices, Versión = 1.0.0.0, Cultura = neutral, PublicKeyToken = nulo
 (Completamente especificado)
LOG: Appbase = file: /// c: / Dev / TeamE / bin / Release /
LOG: PrivatePath inicial = NULL
Ensamblado de llamada: XxxDevicesService, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null.
===
LOG: este enlace se inicia en el contexto de carga predeterminado.
REGISTRO: utilizando el archivo de configuración de la aplicación: c: \ TeamE \ bin \ Release \ XxxDevicesService.vshost.exe.Config
LOG: utilizando el archivo de configuración del host: 
REGISTRO: utilizando el archivo de configuración de la máquina de C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ config \ machine.config.
REGISTRO: La política no se aplica a la referencia en este momento (enlace de ensamblado privado, personalizado, parcial o basado en la ubicación).
REGISTRO: Intentando descargar un nuevo archivo URL: /// c: /TeamE/bin/Release/XxxDevices.DLL.
ERR: No se pudo completar la configuración del ensamblaje (hr = 0x8007000b). Sondeo terminado.

  StackTrace:
       en XxxDevicesService.Program.Main (String [] args)
       en System.AppDomain._nExecuteAssembly (ensamblado RuntimeAssembly, String [] args)
       en Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly ()
       en System.Threading.ExecutionContext.Run (ExecutionContext executionContext, devolución de llamada ContextCallback, estado del objeto, booleano ignoreSyncCtx)
       en System.Threading.ExecutionContext.Run (ExecutionContext executionContext, devolución de llamada ContextCallback, estado del objeto)
       en System.Threading.ThreadHelper.ThreadStart ()
  InnerException: 

fuente
¿está mezclando código nativo / .net en absoluto?
Keith Nicholas
1
Está en el camino correcto porque esta excepción está asociada con diferencias de bits x86 / x64. Supongo que esta no es una aplicación web, ¿verdad? Además, ¿qué tipo de montaje es XxxDevicesService? ¿Está compilado para una plataforma específica (por ejemplo, 32 bits)? Si es así, debe compilar su plataforma a 32 bits.
Reddog

Respuestas:

121

Las configuraciones de compilación verificadas, como Platform Target, son todas iguales (x86).

Eso no es lo que dice el registro de fallos:

Administrador de ensamblajes cargado desde: C: \ Windows \ Microsoft.NET \ Framework64

Tenga en cuenta el 64 en el nombre, que es el hogar de la versión de 64 bits del marco. Establezca la configuración de la plataforma de destino en su proyecto EXE , no en su proyecto de biblioteca de clases. El proyecto EXE de XxxDevicesService determina el bitness del proceso.

Hans Passant
fuente
6
Y mientras verifica el proyecto EXE, verifique Debug y Release. : /
chris
44

Después de que dejé de golpearme la cabeza con el escritorio pensando en toda la semana que pasé resolviendo este problema, estoy compartiendo lo que funcionó para mí. Tengo Win7 de 64 bits, Oracle Client de 32 bits, y tengo mi proyecto MVC 5 configurado para ejecutarse en la plataforma x86 debido al bitness de Oracle. Seguí recibiendo los mismos errores:

No se pudo cargar el archivo o ensamblado 'Oracle.DataAccess' o una de sus dependencias. Se intentó cargar un programa con un formato incorrecto.

Recargué los paquetes NuGet, usé copias de las DLL que funcionaron para otros en diferentes aplicaciones, configuré la base de código en el ensamblado dependiente para que apunte a la carpeta bin de mi proyecto, probé CopyLocal como verdadero o falso, probé todo. Finalmente, había hecho lo suficiente, quería verificar mi código y, como nuevo contratista, no tenía configurada la subversión. Mientras buscaba una manera de conectarlo a VS, tropecé con la respuesta. Lo que encontré funcionó fue desmarcar la opción "Usar la versión de 64 bits de IIS Express para sitios web y proyectos" en la sección Proyectos y soluciones => Proyectos web en el menú Herramientas => Opciones.

Joey Morgan
fuente
3
¡Qué salvavidas! Gracias. Para mí, tuve que verificar esto, ya que mi proyecto es efectivamente x64. ¡¡¡Gracias de nuevo!!!
víbora
Después de toda la ayuda que he recibido aquí, ¡estoy muy contento de haber podido pagar parte de ella!
Joseph Morgan
3
Para aquellos que usan IIS local, asegúrese de que la opción "Habilitar aplicaciones de 32 bits" de su grupo de aplicaciones (en Configuración avanzada) esté establecida en Verdadero .
Eric Eskildsen
Un apéndice al comentario de @ EricEskildsen anterior sobre "habilitar aplicaciones de 32 bits" en el grupo de aplicaciones, incluso si no desea hacer eso en el entorno en vivo, activar ese interruptor puede proporcionar pistas adicionales sobre si se enfrenta a un 32 -Problema de bits / 64 bits o algo más.
a CVn
¡Auge! Eso fue todo.
itslittlejohn
21

Lo que encontré que funcionó fue comprobar la opción "Usar la versión de 64 bits de IIS Express para sitios web y proyectos" en la sección Proyectos y soluciones => Proyectos web en el menú Herramientas => Opciones.

Lucy Zhang
fuente
tu eres el salvador. +1
Amit Kumar
Reinstalé VS y estaba solucionando este problema (gracias, esta solución funcionó). La moraleja de la historia para mí es que si sé que no he cambiado ningún código para empezar, tal vez debería mirar primero la configuración de VS.
taylorswiftfan
La casilla de verificación de @Lucy 'Usar la versión de 64 bits de IIS Express para sitios web y proyectos' está deshabilitada
k_kumar
Por favor, dile a Lucy
k_kumar
12

Por lo general, puede ocurrir cuando cambió el marco de destino de .csproj y lo revertió a lo que comenzó.

Asegúrese de 1 si la versión de tiempo de ejecución compatible = "un tiempo de ejecución diferente del objetivo del proyecto cs" en la etiqueta de inicio en app.config.

Asegúrese de 2 Eso también significa verificar otros archivos autogenerados o de otro tipo en la carpeta de propiedades para ver si no hay más desajustes de tiempo de ejecución entre estos archivos y uno que está definido en el archivo .csproj.

Estos pueden ahorrarle mucho tiempo antes de comenzar a probar diferentes cosas con las propiedades del proyecto para superar el error.

Purvin
fuente
Me encontré con un problema similar y tu respuesta fue la solución para la mía. Mi app.config tenía un tiempo de ejecución compatible diferente.
Krisztián Kis
9

Tuve el mismo problema aunque tengo Windows 7 de 64 bits y estaba cargando una DLL de 64 bits b / c en las propiedades del proyecto | Compilación Había marcado "Preferir 32 bits". (No sé por qué está configurado de forma predeterminada). Una vez que desmarqué eso, todo salió bien

SN
fuente
1
Igual que aquí. Esto hizo el truco. Se hizo referencia a un ensamblado de 64 bits y la configuración de compilación activa se estableció en Cualquier CPU, pero debido a esta configuración de "preferir 32 bits", se supone que se usó 32 bits para ejecutar la aplicación y causó los problemas.
Bernoulli IT
Elegí cualquier CPU en lugar de x86 en modo de depuración y funcionó como un encanto.
Cardi DeMonaco Jr
7

También puede obtener esta excepción cuando su aplicación tiene como destino .NET Framework 4.5 (por ejemplo) y tiene la siguiente app.config:

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

Cuando intente iniciar la depuración de la aplicación, obtendrá BadImageFormatException.

Eliminar la línea que declara la versión v2.0 borrará el error.

Tuve este problema recientemente cuando intenté cambiar la plataforma de destino de un antiguo proyecto .NET 2.0 a .NET 4.5.

Cédric V
fuente
6

Antecedentes

Comenzamos a recibir esto hoy cuando cambiamos nuestro servicio WCF de AnyCPU a x64 en un servidor Windows 2012 R2 que ejecuta IIS 6.2.

Primero verificamos el único ensamblado al que se hace referencia 10 veces, para asegurarnos de que en realidad no era un dll x86. A continuación, verificamos el grupo de aplicaciones varias veces para asegurarnos de que no habilita aplicaciones de 32 bits.

En un capricho, traté de alternar el ajuste. Resulta que los grupos de aplicaciones en IIS tenían por defecto un valor de Habilitar aplicaciones de 32 bits de Falso, pero IIS lo ignoraba en nuestro servidor por alguna razón y siempre ejecutaba nuestro servicio en modo x86.

Solución

  • Seleccione el grupo de aplicaciones.
  • Elija Establecer valores predeterminados del grupo de aplicaciones ... o Configuración avanzada ... .
  • Cambiar Habilitar aplicaciones de 32 bits a Verdadero.
  • Haga clic en Aceptar .
  • Elija Establecer valores predeterminados del grupo de aplicaciones ... o Configuración avanzada ... nuevamente.
  • Cambiar Habilitar aplicaciones de 32 bitsVuelva a a Falso.
  • Haga clic en Aceptar .
JoelC
fuente
4

Solucioné este problema cambiando la aplicación web para usar un "Grupo de aplicaciones" diferente.

Cocu_1012
fuente
4

Para cualquiera que pueda llegar aquí más tarde ... Nada funcionó para mí. Todas mis asambleas estuvieron bien. Tenía una configuración de aplicación en uno de mis proyectos de Visual Studio que no debería haber estado allí. Así que asegúrese de que se necesite el archivo de configuración de su aplicación.

Eliminé la configuración adicional de la aplicación y funcionó.

McSick
fuente
Me lo arregló. ¡Mi App.config estaba configurando mi aplicación .NET 4.5.1 en 2.0 CLR!
Jared Thirsk
4

Compilación de destino Servidor de destino x64 Alojamiento IIS de 64 bits

Si la compilación de la aplicación se dirige a un sistema operativo de 64 bits, en el servidor de 64 bits que aloja el IIS, configure la habilitación de la aplicación de 32 bits en el grupo de aplicaciones que ejecuta el sitio web / aplicación web en falso.

ingrese la descripción de la imagen aquí

VK_217
fuente
2

Determine el grupo de aplicaciones utilizado por la aplicación y establezca la propiedad de estableciendo Habilitar aplicaciones de 32 bits en Verdadero. Esto se puede hacer mediante la configuración avanzada del grupo de aplicaciones.

Anand
fuente
2

Al crear aplicaciones para plataformas de 32 o 64 bits (mi experiencia es con Visual Studio 2010), no confíe en Configuration Manager para configurar la plataforma correcta para el ejecutable. Incluso si el CM tiene x86 seleccionado para la aplicación, verifique las propiedades del proyecto (pestaña Compilación): aún podría decir "Cualquier CPU" allí. Y si ejecuta un ejecutable "Cualquier CPU" en una plataforma de 64 bits, se ejecutará en modo de 64 bits y se negará a cargar las DLL que lo acompañan que fueron creadas para la plataforma x86.

Jeremy Tinkler
fuente
1

Elimine su dependencia de System.Runtime en su Web.Config, funcionó para mí:

<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
fuente
Para mí fue el System.Net.Http. Gracias por eso.
Snickbrack
1

Para .NET Core , existe un error de Visual Studio 2017 que puede hacer que la página de compilación de propiedades del proyecto muestre el destino de plataforma incorrecto. Una vez que descubra que el problema es, las soluciones son bastante fáciles. Puede cambiar el objetivo a otro valor y luego volver a cambiarlo.

Alternativamente, puede agregar un identificador de tiempo de ejecución al .csproj. Si necesita que su .exe se ejecute como x86 para que pueda cargar una DLL nativa x86, agregue este elemento dentro de PropertyGroup:

<RuntimeIdentifier>win-x86</RuntimeIdentifier>

Un buen lugar para poner esto es justo después del elemento TargetFrameworko TargetFrameworks.

Edward Brey
fuente
1

Me sorprende que nadie más haya mencionado esto, así que lo comparto en caso de que nada de lo anterior ayude (mi caso).

Lo que estaba sucediendo era que una instancia de VBCSCompiler.exe estaba bloqueada de alguna manera y, de hecho, no liberaba los identificadores de archivos para permitir que nuevas instancias escribieran correctamente los nuevos archivos y estaba causando el problema. Esto se hizo evidente cuando intenté eliminar la carpeta "bin" y se quejaba de que otro proceso estaba usando archivos allí.

Cerré VS, abrí el administrador de tareas, busqué y terminé todas las instancias de VBCSCompiler y eliminé la carpeta "bin" para volver a donde estaba.

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

Jorge
fuente
Mi solución también fue eliminar todos los directorios bin y debug.
gabnaim
0

Para cualquiera que pueda llegar aquí más tarde ...
Para la solución de escritorio obtuve una BadImageFormatExceptionexcepción.
Todas las opciones de compilación del proyecto estaban bien (todasx86 ). Pero el proyecto de solución de inicio se cambió a algún otro proyecto (proyecto de biblioteca de clases).

Cambiar el proyecto de inicio al original (proyecto de aplicación .exe) fue una solución en mi caso

Fabio
fuente
0

Cuando enfrenté este problema, lo siguiente me lo resolvió:

Estaba llamando a una dll de OpenCV desde dentro de otro exe, mi dll no contenía las dll de opencv ya necesarias como highgui, features2d, etc. disponibles en la carpeta de mi archivo exe. Copié todos estos en el directorio de mi proyecto exe y de repente funcionó.

Ali Nejad
fuente
0

Este error "No se pudo cargar el archivo o ensamblado 'ejemplo' o una de sus dependencias. Se intentó cargar un programa con un formato incorrecto" generalmente se debe a una configuración incorrecta del grupo de aplicaciones.

  1. Asegúrese de que el AppPool en el que se está ejecutando su sitio tenga "Habilitar aplicaciones de 32 bits" configurado en Falso.
  2. Asegúrese de que está utilizando la versión correcta para su plataforma.
  3. Si recibe este error en un sitio web, asegúrese de que su grupo de aplicaciones esté configurado para ejecutarse en el modo correcto (los sitios 3.0 deben ejecutarse en modo de 64 bits)
  4. También debe asegurarse de que la referencia a ese ensamblado en Visual Studio apunte al archivo correcto en la carpeta de paquetes.
  5. Asegúrese de tener la versión correcta de la dll instalada en el GAC para sitios 2.0.
  6. Esto también puede deberse a que WSODLibs se promociona con el proyecto web.
Ben Petersen
fuente