Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assembly binding and redirect

I have an EXE that reference a DLL - for this example I'll call it TestDLL.dll.
The EXE is written in C# and the DLL is written in VB .Net.

I created a demo assembly version of the DLL - for example - TestDLL.dll version 1.0.0.0.
I want to compile the EXE with a reference to the demo version DLL (1.0.0.0). Afterwards - I want the EXE to use the same DLL, but the one I'll put in the GAC, of any version.
In order to do that, I set the "Copy Local" property of the DLL's reference to FALSE.

My goal is for example - after compiling, I'll put in the GAC TestDLL.dll with assembly version 2.1.6.0, and the EXE will find it using the assembly redirect binding. For that, I used a config file. I used this link to create it:
http://msdn.microsoft.com/en-us/library/7wd6ex19(v=vs.71).aspx

So my config file looks about like this:

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
       <dependentAssembly>
         <assemblyIdentity name="myAssembly"
                           publicKeyToken="32ab4ba45e0a69a1"
                           culture="en-us" />
         <!-- Assembly versions can be redirected in application, publisher policy, or machine configuration files. -->
         <bindingRedirect oldVersion="1.0.0.0"
                          newVersion="2.1.6.0"/>
       </dependentAssembly>
      </assemblyBinding>
   </runtime>
</configuration>

The problem is that after doing all that, I run the EXE and when accessing the dll, I get the famous error: System.IO.FileNotFoundException: Could not load file or assembly 'TestDLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9d8162944bd6fdc7' or one of its dependencies. The system cannot find the file specified. File name: 'TestDLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9d8162944bd6fdc7'

Meaning, the EXE can't find the original DLL I referenced to. I know that I can just "reference" the GAC or use reflection, but I don't want to - since this EXE is supposed to work only this way.

Does anyone know what's the problem and how to fix it?
Thanks

like image 346
GG Hendrix Avatar asked Apr 16 '12 14:04

GG Hendrix


1 Answers

Make sure that you have set the proper publicKeyToken. In the code you have shown you are using publicKeyToken="32ab4ba45e0a69a1" which is the public key token from the MSDN link. This obviously is not the public key token of your assembly. For this to work you need to have both assemblies (1.0.0.0 and 2.1.6.0) signed with the same key. To extract the public key token you could use the sn.exe tool or looked at the exception stack trace you are getting (it is telling you that publicKeyToken="9d8162944bd6fdc7"):

sn.exe -Tp myassembly.dll

But if the assembly that the executable was compiled against was not signed with the same key this won't work.

Also I see that you have set the culture="en-us" but does your assembly use this culture? You could also try culture="Neutral".

Finally make sure that you have deployed the proper version of the assembly into the GAC.

like image 130
Darin Dimitrov Avatar answered Sep 19 '22 17:09

Darin Dimitrov