Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I load an older version of a .NET assembly?

Tags:

c#

.net

I have a WPF/C# application that references .NET 4.0 assemblies. However, within the application is a text editor that needs to 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 seems like that's unfortunately by design.

I tried following the proposed solutions in this stack overflow post. However, the linked webpages' solutions don't work and a remoting process seems like overkill. Does anyone know a better and/or easier way to load older .NET assemblies at runtime?

like image 305
Craig Avatar asked Oct 31 '11 21:10

Craig


People also ask

How do I install an older version of .NET framework?

NET Framework are in-place updates, you cannot install an earlier version of the . NET Framework 4. x on a system that already has a later version installed. On Windows versions before Windows 8, if you do choose to remove .

Where are .NET assemblies stored?

NET applications. Assemblies are loaded out of the application folder or a special private bin folder (like ASP.NET applications) and it all works as you would expect.

Can I install multiple versions of .NET Framework?

It is safe to install multiple versions of the . NET Framework on your computer.


2 Answers

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

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

Put the following lines in your app.config file:

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

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

like image 196
Jean Hominal Avatar answered Sep 22 '22 21:09

Jean Hominal


I've done this before, albeit from assemblies that weren't in the GAC: Mine were being loaded from byte arrays, but I could easily have different versions of the same assembly.

The solution was to handle the AssemblyResolve event of the AppDomain, so that you can ensure that the assembly you require is returned. In your case this could be fairly simple, as you only care when doing this particular invocation. The rest of the time you'd take the default and not handle the even at all.

A possible example might 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 crude, but it'll give a idea of the process - you handle the assemblyresolve, and return what you need. The contents of your handler will likely be different as I'm not sure your assembly will be present in the CurrentDomain.GetAssemblies() list.

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

Notes: This was used in .Net 3.5, not 4, but did work for different versions. You may need @Jean's solution to load 3.5 assemblies in 4.

like image 21
Jon Egerton Avatar answered Sep 22 '22 21:09

Jon Egerton