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?
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 .
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.
It is safe to install multiple versions of the . NET Framework on your computer.
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.
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.
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