21 de marzo de 2010

Detectando errores de bindeo de assemblies

A veces, cuando la aplicación que estamos desarrollando esta dividida en muchos assemblies, detectar un problema de referencias (ya sea un problema de versionado o directamente la falta de un determinado assembly) puede resultar bastante difícil.

El error que el runtime muestra es algo parecido a lo siguiente:

System.IO.FileLoadException: Could not load file or assembly 'B, Version=1.1.0.0, Culture=neutral, PublicKeyToken=1735b5aafe024a29' or one of its dependencies.
The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'B, Version=1.1.0.0, Culture=neutral, PublicKeyToken=1735b5aafe024a29'
at A.Class1..ctor()
at ConsoleApplication1.Program.Main(String[] args) in C:\VSProjects\AssemblyBindingTest\ConsoleApplication1\Program.cs:line 17

WRN: Assembly binding logging is turned OFF.
To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
Note: There is some performance penalty associated with assembly bind failure logging.
To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].

En este ejemplo, una aplicación de consola referencia a un assembly A.dll, y este assembly a su vez referencia a otro assembly B.dll
La versión correcta de B.dll debería ser la 1.1.0.0, pero en la carpeta donde se ejecuta la aplicación, deliberadamente hice deploy de la versión 2.1.0.0
Lo único que este mensaje de error me dice, es que no se pudo levantar el assembly 'B, Version=1.1.0.0, Culture=neutral, PublicKeyToken=1735b5aafe024a29', o alguna de sus dependencias.

Lo cual no me dice mucho para resolver mi problema, en especial si esto ocurre en un ambiente con decenas de assemblies e inclusive algunos quizás no desarrollados por mi, sino por terceros.

Lo importante del mensaje es lo siguiente:
WRN: Assembly binding logging is turned OFF.
To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.

Aquí me dice que asignando el valor 1 a la entrada del registro HKLM\Software\Microsoft\Fusion!EnableLog se puede habilitar el "Assembly binding logging", vamos a hacerlo y veamos como cambia el mensaje de error que nos muestra el runtime:

System.IO.FileLoadException: Could not load file or assembly 'B, Version=1.1.0.0, Culture=neutral, PublicKeyToken=1735b5aafe024a29' or one of its dependencies.
The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'B, Version=1.1.0.0, Culture=neutral, PublicKeyToken=1735b5aafe024a29'
at A.Class1..ctor()
at ConsoleApplication1.Program.Main(String[] args) in C:\VSProjects\AssemblyBindingTest\ConsoleApplication1\Program.cs:line 17

=== Pre-bind state information ===
LOG: User = WinXP\Jorge
LOG: DisplayName = B, Version=1.1.0.0, Culture=neutral, PublicKeyToken=1735b5aafe024a29
(Fully-specified)
LOG: Appbase = file:///C:/VSProjects/AssemblyBindingTest/ConsoleApplication1/bin/Debug/
LOG: Initial PrivatePath = NULL
Calling assembly : A, Version=1.1.0.0, Culture=neutral, PublicKeyToken=10f50b7c12e8c3d1.
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using machine configuration file from c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\config\machine.config.
LOG: Post-policy reference: B, Version=1.1.0.0, Culture=neutral, PublicKeyToken=1735b5aafe024a29
LOG: Attempting download of new URL file:///C:/VSProjects/AssemblyBindingTest/ConsoleApplication1/bin/Debug/B.DLL.
WRN: Comparing the assembly name resulted in the mismatch: Major Version
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.

La primer parte del mensaje es igual a lo que obteníamos antes, pero ahora nos indica además el assembly "llamador":
Calling assembly : A, Version=1.1.0.0, Culture=neutral, PublicKeyToken=10f50b7c12e8c3d1.

Y lo mas importante, el motivo por el cual no se pudo realizar el bindeo.
LOG: Attempting download of new URL file:///C:/VSProjects/AssemblyBindingTest/ConsoleApplication1/bin/Debug/B.DLL.
WRN: Comparing the assembly name resulted in the mismatch: Major Version

Con esto sabemos que el assembly que no se pudo bindear es B.dll (y no alguna de sus dependencias, como sugería el mensaje original) y específicamente sabemos que el problema es de versionado (la dll que el runtime encontró es de una versión mayor a la requerida por la aplicación)

Por último, no olvidemos lo que nos decia el mensaje a modo de advertencia sobre habilitar Assembly Binding Logging:
Note: There is some performance penalty associated with assembly bind failure logging.
To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].

Así que para evitar problemas de performance, luego de haber descubierto y solucionado nuestro problema, deshabilitamos el assembly binding logging asignando un 0 a HKLM\Software\Microsoft\Fusion!EnableLog

Espero que sea útil, cualquier comentario será bienvenido !

4 comentarios:

  1. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  2. Auxilioooooooooooooo!!
    Tengo este problema y no se como solucionarlo, no se donde ni que moverle, y no me aparece eso del fusion :(((
    Me podrias decir como hacer paso por paso? POR FAVOR!!
    O si te envío el archivo donde copié todo lo que me sale :(

    ResponderEliminar

  3. Very informative error.Thank you author for posting this kind of errors .



    http://www.wikitechy.com/fix-error/assembly-binding-logging-is-turned-off



    Both are really good.
    Cheers,
    Venkat

    ResponderEliminar

  4. Very informative error.Thank you author for posting this kind of errors .



    http://www.wikitechy.com/fix-error/assembly-binding-logging-is-turned-off



    Both are really good.
    Cheers,
    Venkat

    ResponderEliminar