How to download an old version of .NET assembly?

I have a WPF / C # application that references .NET 4.0 assemblies. However, the application has a text editor that should display C # intellisense, tied to .NET 3.5 assemblies. Thus, I want to be able to load the appropriate .NET 3.5 assemblies at runtime. However, when I try to use:

Assembly.Load() Assembly.LoadFile() Assembly.LoadFrom() 

I always get the latest version from the GAC. Reading their MSDN pages, it looks, unfortunately, in design.

I tried to implement the suggested solutions in this article overflow stack . However, linked web page solutions do not work, and the remote access process seems redundant. Does anyone know a better and / or easier way to load old .NET collections at run time?

+7
source share
5 answers

I did this before, although from assemblies that were not in the GAC: Mine loaded from byte arrays, but I could easily have different versions of the same assembly.

The solution was to handle the AssemblyResolve event for the AppDomain so you can make sure that the required assembly will be returned. In your case, this can be quite simple, since you only need to make this specific call. The rest of the time, you take the default value and do not even process it at all.

A possible example would be:

 public DoSomething() { //Add the handler AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve //Load your assembly... } private System.Reflection.Assembly CurrentDomain_AssemblyResolve(Object sender, ResolveEventArgs e) { foreach (System.Reflection.Assembly a In AppDomain.CurrentDomain.GetAssemblies()) { if (a.FullName == <<The one you need>>) return a } } 

This is pretty rude, but it will give an idea of ​​this process - you will cope with assemblyresolve and return what you need. The contents of your handler will probably be different, because I'm not sure if your assembly will be in the CurrentDomain.GetAssemblies() list.

There are probably more subtle assmeblyresolve examples out there that will handle the GAC version for you.

Notes. This was used in .Net 3.5, not 4, but worked for different versions. You might need @Jean's solution to load 3.5 builds into 4.

+1
source

The AssemblyBinding property can be used in your app.config or web.config, whichever is appropriate.

For example, I interact with Matlab, so I need this ...

 <loadFromRemoteSources enabled="true" /> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="MWArray" publicKeyToken="E1D84A0DA19DB86F" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-2.10.0.0" newVersion="2.10.0.0" /> </dependentAssembly> </assemblyBinding> 

Because the Matlab mechanism I'm working with is compiled (in some crazy way) on a machine using a different copy of the runtime.

You should be able to modify this code to suit your needs.

+1
source

By default, you cannot load assemblies completed for previous versions of the .NET platform on the .NET platform version 4.

However, there is a configuration attribute that allows: http://msdn.microsoft.com/en-us/library/bbx34a2h.aspx

Place the following lines in the app.config file:

 <configuration> <startup useLegacyV2RuntimeActivationPolicy="true|false" > </startup> </configuration> 

There are reasons why this is inactive by default, but I believe that it should be suitable for your use.

0
source

One partial solution I discovered is to use Assembly.ReflectionOnlyLoadFrom (). This method correctly loads older versions of assemblies, although the assembly is loaded into the context only for reflection, that is, you cannot execute code in the assembly. Although this is not a real build, it allows you to use most of the intellisense scripts I'm working on.

One lingering issue is mscorlib. When trying to use the assembly returned from ReflectionOnlyLoadFrom, an exception was thrown for an older version of mscorlib: "System.TypeLoadException: could not load the type" System.Object "from the assembly" mscorlib, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089 ' because the parent does not exist. "

0
source

I solved this problem using ReflectionOnlyLoadFrom () to load assemblies of any version that I need in read-only mode, for use with reflection only. When it comes to the fact that you cannot do this for mscorlib (you can request 2.0, but you will get 4.0 back from the call), I handled this by filtering the return types based on the version I need. In the end, in this mode, you can only check types in the DLL using reflection, and actually do nothing with them, so you can easily filter the list of returned types as needed.

Here are the types that I have filtered out of mscorlib 4.0 so far, so everything works when an older version of mscorlib is expected:

  /// <summary> /// Types to be hidden from .NET mscorlib 4.0 for older versions. /// </summary> protected static readonly HashSet<Type> HideMscorlib4Types = new HashSet<Type> { // The Action delegates with 0, 2, 3, 4 type parameters were moved from System.Core 3.5 to mscorlib for 4.0 typeof(Action), typeof(Action<,>), typeof(Action<,,>), typeof(Action<,,,>), // The Func delegates with 1 to 5 type parameters were moved from System.Core 3.5 to mscorlib for 4.0 typeof(Func<>), typeof(Func<,>), typeof(Func<,,>), typeof(Func<,,,>), typeof(Func<,,,,>), // Other types moved from System.Core 3.5 to mscorlib 4.0 typeof(TimeZoneInfo), // Hide various types that were new in mscorlib 4.0 typeof(Tuple) }; 
0
source

All Articles