I have a simple application that loads two assemblies at runtime from 2 subfolders through this piece of code:
Assembly.Load("A, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
Assembly.Load("B, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
The directory structure is:
So the expected loading is as follow:
TheApp.exe -> A.dll -> C.dll (version 2.0.0.0)
-> B.dll -> C.dll (version 1.0.0.0)
Please note that C.dll
is signed so both versions should be loaded side by side.
To ensure the application is loading the assemblies from the right places, I added the following to the application config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="B;A" />
</assemblyBinding>
</runtime>
</configuration>
The problem is the application is crashing with the message below whenever started:
=== Pre-bind state information ===
LOG: User = ...
LOG: DisplayName = C, Version=2.0.0.0, Culture=neutral, PublicKeyToken=93a02044a09d059a
(Fully-specified)
LOG: Appbase = file:///D:/Temp/TheApp/bin/Debug/Test/
LOG: Initial PrivatePath = NULL
Calling assembly : A, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: D:\Temp\TheApp\bin\Debug\Test\TheApp.exe.Config
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v2.0.50727\config\machine.config.
LOG: Post-policy reference: C, Version=2.0.0.0, Culture=neutral, PublicKeyToken=93a02044a09d059a
LOG: Attempting download of new URL file:///D:/Temp/TheApp/bin/Debug/Test/C.DLL.
LOG: Attempting download of new URL file:///D:/Temp/TheApp/bin/Debug/Test/C/C.DLL.
LOG: Attempting download of new URL file:///D:/Temp/TheApp/bin/Debug/Test/B/C.DLL.
WRN: Comparing the assembly name resulted in the mismatch: Major Version
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.
QUESTION: Why is the runtime looking at "B" folder only? Why is it not continuing to look for the right version of the shared assembly in the A folder?
EDIT1: I added the <codeBase>
tag as mentioned below, I know have the following in my config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="B;A" />
</assemblyBinding>
<dependentAssembly>
<assemblyIdentity name="C" publicKeyToken="93a02044a09d059a" />
<codeBase version="1.0.0.0" href="B/C.dll"/>
<codeBase version="2.0.0.0" href="A/C.dll"/>
</dependentAssembly>
</runtime>
</configuration>
Still, the problem persists!
See the note on this MSDN page on probing which directly addresses your issue:
If you have multiple versions of an assembly in a directory and you want to reference a particular version of that assembly, you must use the
<codeBase>
element instead of theprivatePath
attribute of the<probing>
element. If you use the<probing>
element, the runtime stops probing the first time it finds an assembly that matches the simple assembly name referenced, whether it is a correct match or not. If it is a correct match, that assembly is used. If it is not a correct match, probing stops and binding fails.
The runtime is looking for the 2.0.0.0 version but finds the 1.0.0.0 version and stops looking.
The final solution is changing the config file to the following:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="B;A" />
<dependentAssembly>
<assemblyIdentity name="C" publicKeyToken="93a02044a09d059a" />
<codeBase version="1.0.0.0" href="B/C.dll"/>
<codeBase version="2.0.0.0" href="A/C.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With