I'm using a pair of unsigned 3rd party assembly libraries that contain windows controls and base types from which I create derived classes. The dlls reside in a subfolder where my application gets installed. Beyond my control, a newer version of the libraries with the same names but built against a later version of the .Net runtime get installed in the same directory as my executable.
This causes my application to throw a BadImageFormatException saying:
Could not load file or assembly 'sharedlibA' [...] This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.
Here's the filesystem structure I'm working with:
[MyappFolder]
|--Myapp.exe
|--sharedlibA.dll (wrong version)
|--sharedlibB.dll (wrong version)
|--bin
|--sharedlibA.dll (need to use this)
|--sharedlibB.dll (need to use this)
I've been reading about the different Assembly loading contexts and creating a separate AppDomain but none of these would seem to work.
Edit
I've removed the probing information from the configuration file as Hans suggested below and subscribed to the AssemblyResolve event, so now all the other dependent assemblies trigger that event EXCEPT for sharedlibA and sharedlibB. They still result in a BadImageFormatException. It looks like the AppBase folder is still getting probed despite the change.
Here's the fusion log:
=== Pre-bind state information ===
LOG: User = ...
LOG: DisplayName = sharedlibA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=643d95c7ce242296
(Fully-specified)
LOG: Appbase = file:///C:/[MyappFolder]
LOG: Initial PrivatePath = NULL
Calling assembly : (Unknown).
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\[MyappFolder]\Myapp.exe.Config
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v2.0.50727\config\machine.config.
LOG: Post-policy reference: sharedlibA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=643d95c7ce242296
LOG: Attempting download of new URL file:///C:/[MyappFolder]/sharedlibA.DLL.
ERR: Failed to complete setup of assembly (hr = 0x8013101b). Probing terminated.
Edit #2
I've solved my specific problem. Answer below.
I solved this problem by adding <codeBase>
elements to the application config file to specify the exact location of each dll. Apparently this works because <codebase>
is checked BEFORE the probing heuristics kick in each time an assembly needs to be loaded.
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="sharedlibA" culture="neutral" publicKeyToken="..." />
<codeBase version="1.0.0.0" href="bin\sharedlibA.dll" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="sharedlibB" culture="neutral" publicKeyToken="..." />
<codeBase version="1.0.0.0" href="bin\sharedlibB.dll" />
</dependentAssembly>
</assemblyBinding>
</runtime>
This really ought to be addressed with "Stop doing that!". A very specific workaround for this is to get rid of the <probing>
element in your .exe.config file so the CLR can no longer find the DLLs. And implement the AppDomain.CurrentDomain.AssemblyResolve event to return the blessed ones.
User contributions licensed under CC BY-SA 3.0