We are often faced with a problem where an assembly fails to load. There could be various reasons for the load failure:
- An assembly being probed could not be located.
- Version mismatch or an assembly of diffrent version was already loaded by the process.
- A dependency could not be found or resolved.
It sometimes is cumbersome to troubleshoot such scenarios and, having had the similar experience a couple of times made me search for a way to achieve it especially on environments where there are no Visual Studio or .NET tools.
I came across Fusion Log Viewer (fuslogvw.exe) which is a part of .NET tools and helps in capturing all assembly binding information on the machine. However, good thing is that it's just a log viewer that comprehends the log files and dumps the information on a neat grid. But, it not required to enable or capture the logs which makes it a perfect fit for production environments.
Using the code
All we need to do is set a couple of registry entries to enable logging. Here are the keys that you can easily configure.
Add the following values to:
Add the following keys:
- ForceLog [DWORD]: Set it to 1 to enable logging information of all assembly bindings on the machine.
- LogFailures [DWORD]: Set it to 1 to enable logging failures during assembly loads.
- LogResourceBinds [DWORD]: Set it to 1 to enable logging information about all resource bindings.
- LogPath [String]: Set it to the folder where you want the log files to be created (e.g. C:\Logs\FusionLog\)
- Make sure you include the backslash after the folder name and that the Folder exists.
- You need to restart the program that you're running to force it to read those registry settings.
You may put these settings in a reg file to set/update the same quickly e.g.
Once again try and repro the scenario where the assembly load failed, open the log folder and there you go... the logs are very easy to read and understand :)
Interpreting the log files
Once you've enabled the logging and restarted your application which fails to load an assembly, you see some log files in fusion log path you have configured. Now:
- The logs are contained in a folder named by the host process which tried to load the assembly.
- The log files inside this folder are named by the assembly which failed to load.
- And, finally the data inside the log file will tell why/how the probing failed.
Here's a sample log content:
<meta http-equiv="Content-Type" content="charset=unicode-1-1-utf-8"><!-- saved from url=(0015)assemblybinder: --><html><pre>
*** Assembly Binder Log Entry (7/3/2014 @ 4:11:21 PM) ***
The operation failed.
Bind result: hr = 0x80131040. No description available.
Assembly manager loaded from: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable C:\Program Files\XXXX\YYYY.exe
--- A detailed error log follows.
=== Pre-bind state information ===
LOG: DisplayName = ABCD, Version=184.108.40.206, Culture=neutral, PublicKeyToken=a38ab61cdab78c6a
LOG: Appbase = file:LOG: Initial PrivatePath = C:\Program Files\XXXX
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = YYYY.exe
Calling assembly : PQRS, Version=220.127.116.11, Culture=neutral, PublicKeyToken=a38ab61cdab78c6a.
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Program Files\XXXX\YYYY.exe.Config
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Post-policy reference: ABCD, Version=18.104.22.168, Culture=neutral, PublicKeyToken=a38ab61cdab78c6a
LOG: GAC Lookup was unsuccessful.
LOG: Attempting download of new URL file:LOG: Assembly download was successful. Attempting setup of file: C:\Program Files\XXXX\ABCD.dll
LOG: Entering run-from-source setup phase.
LOG: Assembly Name is: ABCD, Version=22.214.171.12412, Culture=neutral, PublicKeyToken=a38ab61cdab78c6a
WRN: Comparing the assembly name resulted in the mismatch: Minor Version
ERR: The assembly reference did not match the assembly definition found.
ERR: Run-from-source setup phase failed with hr = 0x80131040.
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.
Here, YYYY.exe loaded an assembly PQRS.dll which has a dependency on ABCD.dll (version 126.96.36.199) but on the machine it could only find ABCD.dll (version 188.8.131.5212).
The log indicates the failure in load because of mismatch in Minor Version of the assembly. Hence, the load of PQRS.dll fails as it's dependent assembly could not be loaded.
[16-Jul-2014 Update]: Added the section <Interpreting the log files> as requested.