viernes, 9 de septiembre de 2011

Excepción BadImageFormatException en IIS 7.5

Ayer tuvimos algún 'pequeño' problema al generar un entorno de prueba de una aplicación web ASP.NET. La situación más o menos vino a ser la siguiente:

Problema:

Al acceder a la dirección web de la aplicación, se produce una excepción de ASP.NET del tipo BadImageFormat.

Solución (¿solución?):

Fácil (yujuu!) El equipo en el que la aplicación está instalada es un Windows 7 en 64 bits, con lo que si está dando esa excepción, el sospechoso más habitual indica que el proyecto en Visual Studio está compilado en 32 bits, así que para solucionar el problema, basta con acceder a las propiedades del proyecto y especificar que la compilación sea compatible con 'Any CPU', tal y como vemos en la siguiente captura (Como el proyecto es en VB.Net, la captura corresponde a las propiedades de un proyecto en ese lenguaje)





Listo. Cambiamos la opción de compilación, compilamos la solución y la instalamos, y a funcionar… un momento, ¿no funciona?

Problema 2:

Al acceder a la aplicación ya compilada correctamente, aparece una nueva excepción. Esta excepción, de la que no tengo captura, decía que no podía cargarse en memoria uno de los ensamblados referenciados por la aplicación (en concreto se trata de un ensamblado Interop) toca 'bucear' un poco en la excepción y darle un poco al 'coco'… Vale, ya lo tenemos!!!

Solución 2:

La segunda excepción está directamente relacionada con la primera, ya que al compilar la aplicación para 'Any CPU' hemos conseguido que la aplicación arranque correctamente en IIS (64 bits) peeero cuando esa aplicación realiza una instancia del componente Interop (compilado en 32 bits) resulta que no puede crear los objetos porque no son compatibles. Menos mal que IIS 7.5 tiene la opción de permitir aplicaciones en 32 bits… ¿dónde?

Vamos al listado de los Application Pools, y en el Pool asociado a la aplicación vamos a las opciones avanzadas:



Aceptamos el cambio, IISReset por si acaso, y a volar!!!!



Explicaciones:

El primer error como he comentado estaba provocado por el tipo de compilación del proyecto. Al compilarlo en 32 bits, los procesos de IIS que se ejecutan en 64 bits no eran capaces de arrancar la aplicación, con lo que cambiamos el modo de compilación a 'Any CPU' para que el compilado sea capaz de adaptarse tanto a 64 como a 32 bits (opción recomendada)

El segundo error estaba provocado precisamente por el cambio realizado en el primer punto, ya que al iniciar la aplicación en 64 bits, cualquier instancia que se realice de ensamblados o dll's compilados en 32 bits, sencillamente 'casca'

Consideración Especial:

Vistos los dos problemas que nos aparecieron, entiendo que la directa hubiera sido configurar el IIS para que permitiera aplicaciones en 32 bits, pero, ¿dónde está la gracia si lo solucionamos tan rápido y sin tener que pensar?

Nota: El segundo problema (ensamblado Interop) en este caso parecía claro que era por una compilación en 32 bits, eso NO quiere decir que en todos los casos esta solución sea válida al 100%.

No hay comentarios: