Use a specific version of a dll in C# - c#

I have a project where I would want to use some specific version of a dll.
The GAC contains couple of versions of that dll (new & old), I would want to use the old when running the program.
Issue is that the newest dll is always picked-up from the GAC.
Would you know if there is a way to either:
Force the usage the dll that is in the run folder (the one I'm referencing in my solution, working fine in debug).
Force the usage of the old version of the dll from the GAC.
Thank you!

You can use a binding redirect in your app.config or web.config in the runtime node:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
</appSettings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Make sure you have the correct publicKeyToken and know which versions you want to redirect to what version.
(You can check a publicKeyToken of a DLL like this with this info.)
MSDN Documentation
You can also generate these for an entire solution using the Package Manager Console
Get-Project -All | Add-BindingRedirect
This will update all app.config files and add the binding redirect.

When you have added the library to your project and you collapse the 'References'-node of the project tree, you'll see the added library. When you select it and click the 'Properties'-node of the context menu, you can specify if a specific version of the library should be used and which version to use. Simply set 'Specific Version' to true and specify the Version number. Then you don't have to cope with the question where the version you want is loaded from.

Have you try to "Redirecting Assembly Versions" in your app.config? http://msdn.microsoft.com/en-us/library/7wd6ex19(v=vs.110).aspx

Related

Dependent Assembly loading via configuration

I have a visual studio project with is running absolutely fine.
But a new client requirement comes up for deployment for placing the different dlls in different folders.
We have a framework dll which can be used in a different project. There are some third-party dlls on which this framework dll depends upon. So when I use this dll from my project every dependent dll is copied to my local on the build as CopyLocal property is true.
But now with new requirement we can not have CopyLocal property set as True. The client wants no local copy of any dll, rather he wants framework related dll in some location. When I am doing this the dependent DLL's are not getting loded.
I know I have two options:
I can put them in GAC, but I don't want to do this as I want them to support xcopy.
Using reflection(But I am not sure of this that is this the right approach)
Can we do anything using configurations??
You can configure assembly probing paths using the <probing> configuration element:
Specifies application base subdirectories for the common language runtime to search when loading assemblies.
Example from MSDN:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin;bin2\subbin;bin3"/>
</assemblyBinding>
</runtime>
</configuration>
However, if the assemblies in question reside outside the application base ("which is the root location where the application is being executed"), you have the <codeBase> configuration element:
Specifies where the common language runtime can find an assembly.
Example from MSDN:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="myAssembly"
publicKeyToken="32ab4ba45e0a69a1"
culture="neutral" />
<codeBase version="2.0.0.0"
href="http://www.litwareinc.com/myAssembly.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
For the exact details of how the runtime locates assemblies you can refer to this MSDN article.
As OP pointed out, unfortunately codeBase element is a usable option for strong named assemblies only. For private assemblies you need a workaround. Some viable ideas can be found in this discussion such as:
file system links (NTFS junction point) + probing element or AppDomainSetup.PrivateBinPath
AppDomain.CurrentDomain.AssemblyResolve event
I've tested the latter and can confirm it works:
AppDomain.CurrentDomain.AssemblyResolve += (s, e) =>
Assembly.LoadFile(Path.Combine(Settings.Default.AssemblyPath, Path.ChangeExtension(e.Name.Substring(0, e.Name.IndexOf(',')), ".dll")));

C#, Shared Assemblies, publisher policy not working, MS VS .NET 2013

I can't figured out how to use a publisher policy correctly and I seem to have an similiar issue as related to:
How to make Publisher Policy file redirect assembly request
I've created shared assemply named "SharedAssembly.dll" in version "1.0.0.0", and then in version "2.0.0.0". Both are instaled in GAC (MSIL_GAC, target is .NET Framework 4.5).
I've created following publisher policy file *.xml (redirecting to an older version "1.0.0.0" is on purpose behaviour):
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity
name="SharedAssembly"
publicKeyToken="89f6ea550599ca14"
culture="neutral"/>
<bindingRedirect oldVersion="2.0.0.0"
newVersion="1.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Then I've created the publisher policy assembly using the command:
al /link:App.config /out:policy.2.0.SharedAssembly.dll /keyf:F:\VisualStudio\klucz.snk /v:1.0.0.0 /platform:anycpu
Of course, I installed it into GAC.
Then I created a new Console Application, I added reference to the "SharedAssembly.dll", but it doesn't work :(
It still connects with the 2.0.0.0 version of my shared assembly.
I tried many advices, as using fuslogvw.exe (no errors shown), getting rid of the "culture" attribute, etc., but it doesn't help.
I think the problem is not that I want to point to the older version of .dll?
Please help me to fix that issue, cause I've tried so many things and yet I can't make it work.

Could not load file or assembly 'ABC.dll, Version=5.5.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies

We have an C# class library project which was created using .Net framework 3.5.In that C# project we add an assembly ABC.dll build using VS 2008 3.5 framework with version 5.5.0.0.
Now when we add ABC.dll with an updated version of 6.6.2.1 then in Designer view still get an error:
Could not load file or assembly 'ABC.dll, Version=5.5.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
I am really stuck and cannot find the reason in-spite of adding 6.6.2.1 why the project is asking for 5.5.0.0 version dll?
We are now using C# Express Edition 2010 to open the project.
Make sure that the reference is present and any dependent assemblies are referenced appropriately; you may need to make sure that the references have the property "SpecificVersion" set "false".
If the assemblies are present and the correct version - try cleaning the solution (Build | Clean Solution), as sometimes old versions linger in the project output folders and confuse Visual Studio.
You should be able to add an app.config file, telling your library which file to use when the .dll is called.
This should contain something like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="ABC"
publicKeyToken="8fe83dea738b45b7"
culture="neutral"/>
<bindingRedirect oldVersion="5.5.0.0"
newVersion=" 6.6.2.1"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

How can you make a c# project ignore the version number of an assembly?

I am working on a project that references dlls from another product. The product has a release each year and the assemblies version changes for each one, although the methods stay the same.
When I run a build of my project for 2010 when I try and run it for 2009 it throws an error because it is dependent on a different version. Is there a way around this?
If you're referring to a problem at runtime after swapping versions of your assembly without performing a rebuild of the program referencing your newly built assembly, you'll want to use a <bindingRedirect> directive to your program's App.config (or Web.config, if you're talking about a web site.)
bindingRedirect is used to instruct the .NET Framework that it's OK to use a version of an assembly other than the one the application was originally compiled against. By default, the CLR wants to see the same version of a DLL that your application was referencing during build, and if it doesn't it will throw an exception.
Try selecting the reference, and in property window set Specific Version as false.
It is possible to map different .net version of assembly in app.config that you put in application root folder
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Waters.ACQUITY.Remote"
publicKeyToken="6c13fd0b3604de03"
culture="neutral" />
<bindingRedirect oldVersion="1.40.0.0"
newVersion="1.60.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
This is solution when assembly you have referenced has references inside it to another specifc library version.
It happens when at compilation time "Specific version" is set to true. To avoid this problem it should be false.

Error Using JSON.NET

I am trying to use JSON.NET and after including the .dll and trying to use one of the methods I get this error:
Could not load file or assembly 'Newtonsoft.Json.Net35, Version=4.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The system cannot find the file specified.
Any know why I might be this error?
Two things to check:
(1) You may have to "Unblock" the DLL. By default, when you download a .zip file from the Internet, that file, and all .dll or .exe files extracted from that .zip file, are given a file system attribute that prevents them from loading and executing. Right-click on the DLL in Windows Explorer, choose "Properties", and in the resulting dialog box click on the "Unblock" button. Or better yet, do that for the .zip file, and then re-extract all the files.
(2) The Newtonsoft JSON.NET library comes in five flavors: one each for .NET 2.0, 3.5, 4.0, Silverlight, and Windows Phone. You need to use the right one for your particular environment. I presume that this is a .NET 3.5 project?
In my case, I resolved this problem once I realized that a library that I was using was itself using the Json.NET but with the earlier version (3.5). Linking the second library to the new Json.NET version solved the issue.
Hope this helps.
You need to download release 1 instead of release 2 of the Newtonsoft.Json.
try to add assembly binding redirect to app config like:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.5.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Related posts:
System.IO.FileNotFoundException
At least one module has an unresolved import
Debugging tests that require an external dll

Categories