LoaderExceptions when building in Release mode – sgen.exe

Recently we faced a problem where an application would build and run in debug mode but it would not do the same in release, throwing the following error at the end of a build.

sgen = http://msdn.microsoft.com/en-us/library/bk3w6240(v=VS.100).aspx

Knowing that sgen is responsible for generating the xml serialisation assembly for the application, the error was most likely related to an assembly that was injected during runtime into the AppDomain, in release mode. As sgen loads all the assemblies immediately, we see an error.

In debug mode the application appears to be running correctly but it would fail in release mode, when the assembly is loaded.

Now, the $1M question. Which assembly was causing this error?

The error message in VS output window was not very informative, so we set the build log to “diagnostic”, rebuilt the application in release mode and watched the output window.

post2-1

Target GenerateSerializationAssemblies:
  Building target "GenerateSerializationAssemblies" completely.
  Output file "obj\Release\ClientWebsite.XmlSerializers.dll" does not exist.
  Using "SGen" task from assembly "Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
  Task "SGen"
    Command:
    C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\sgen.exe /assembly:D:\projects\repo\wwwroot\obj\Release\ClientWebsite.dll /proxytypes /reference:bin\(over 30 references)
    The "SGen" task is using "sgen.exe" from "C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\sgen.exe".
    Microsoft (R) Xml Serialization support utility
    [Microsoft (R) .NET Framework, Version 2.0.50727.3038]
    Copyright (C) Microsoft Corporation. All rights reserved.
    SGEN : error : Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
 
    If you would like more help, please type "sgen /?".
    The command exited with code 1.
  Done executing task "SGen" -- FAILED.
Done building target "GenerateSerializationAssemblies" in project "Site.EPS.csproj" -- FAILED.

Retrieve the LoaderExceptions property for more information. Right.

So this error message was also not very informative, we had to dig a little bit deeper.

At this point we know that sgen cannot bind the assembly, so we are going to have a look at the binding logs via assembly binding log viewer aka fuslogvw.exe.

fuslogvw.exe = http://msdn.microsoft.com/en-us/library/e74a18c4%28v=VS.100%29.aspx

To enable fusion logging, the following DWORD registry key has to be set:

post2-2

HKLM\Software\Microsoft\Fusion!EnableLog 1

Start fusion log viewer and configure it to log assembly binding failures to disk:

post2-3

post2-4

Now rebuild the application to log the errors and refresh the fusion log viewer window. You should see something similar to the following:

*** Assembly Binder Log Entry  (10/11/2010 @ 14:48:49) ***
 
The operation failed.
Bind result: hr = 0x80070002. The system cannot find the file specified.
 
Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll
Running under executable  C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\sgen.exe
--- A detailed error log follows. 
 
=== Pre-bind state information ===
LOG: User = FCUK\Nimesh.Manmohanlal
LOG: DisplayName = EPiServer, Version=5.1.422.122, Culture=neutral, PublicKeyToken=8fe83dea738b45b7
 (Fully-specified)
LOG: Appbase = file:///C:/Program Files/Microsoft SDKs/Windows/v6.0A/bin/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = NULL
Calling assembly : EPiCode.Caching, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in LoadFrom load context.
WRN: Native image will not be probed in LoadFrom context. Native image will only be probed in default load context, like with Assembly.Load().
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: EPiServer, Version=5.1.422.122, Culture=neutral, PublicKeyToken=8fe83dea738b45b7
LOG: GAC Lookup was unsuccessful.
LOG: Attempting download of new URL file:///C:/Program Files/Microsoft SDKs/Windows/v6.0A/bin/EPiServer.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/Microsoft SDKs/Windows/v6.0A/bin/EPiServer/EPiServer.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/Microsoft SDKs/Windows/v6.0A/bin/EPiServer.EXE.
LOG: Attempting download of new URL file:///C:/Program Files/Microsoft SDKs/Windows/v6.0A/bin/EPiServer/EPiServer.EXE.
LOG: Attempting download of new URL file:///C:/projects/MyWebsite/References/EPiServer.DLL.
LOG: Attempting download of new URL file:///C:/projects/MyWebsite/References/EPiServer/EPiServer.DLL.
LOG: Attempting download of new URL file:///C:/projects/MyWebsite/References/EPiServer.EXE.
LOG: Attempting download of new URL file:///C:/projects/MyWebsite/References/EPiServer/EPiServer.EXE.
LOG: All probing URLs attempted and failed.

Finally we found the cause of our problem. We had a third party assembly that was built using a different version of EPiServer (5.1.422.122), so when sgen.exe tried to load the project assemblies and all of the dependencies it failed.

The fix was to rebuild the third party assembly using the correct version of EPiServer (5.2.375.236).

This happened because we upgraded an EPiServer web application project from CMS5 to CMS5 R2. The application was migrated succesfully but the third party assemblies were not taken in consideration and the error only manifested itself further down the line.

The morale of the story is, if you perform an application upgrade, make sure you also upgrade all your third party libraries that have dependencies on your product.