views:

369

answers:

2

Hello,

I've an application that is based on .NET 2 runtime. I want to add a little bit of support for .NET 4 but don't want to (in the short term), convert the whole application (which is very large) to target .NET 4.

I tried the 'obvious' approach of creating an application .config file, having this:

<startup useLegacyV2RuntimeActivationPolicy="true">
  <supportedRuntime version="v4.0" />
</startup>

but I ran into some problems that I noted here.

I got the idea of creating a separate app domain. To test it, I created a WinForm project targeting .NET 2. I then created a class library targeting .NET 4. In my WinForm project, I added the following code:

        AppDomainSetup setup = new AppDomainSetup();
        setup.ApplicationBase = "path to .NET 4 assembly";
        setup.ConfigurationFile = System.Environment.CurrentDirectory + 
          "\\DotNet4AppDomain.exe.config";

        // Set up the Evidence
        Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
        Evidence evidence = new Evidence(baseEvidence);

        // Create the AppDomain      
        AppDomain dotNet4AppDomain = AppDomain.CreateDomain("DotNet4AppDomain", evidence, setup);
        try
        {
            Assembly doNet4Assembly = dotNet4AppDomain.Load(
               new AssemblyName("MyDotNet4Assembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=66f0dac1b575e793"));
            MessageBox.Show(doNet4Assembly.FullName);
        }
        finally
        {
            AppDomain.Unload(dotNet4AppDomain);
        }

My DotNet4AppDomain.exe.config file looks like this:

<startup useLegacyV2RuntimeActivationPolicy="true">
  <supportedRuntime version="v4.0" />
</startup>

Unfortunately, this throws the BadImageFormatException when dotNet4AppDomain.Load is executed. Am I doing something wrong in my code, or is what I'm trying to do just not going to work?

Thank you!

A: 

You target the 2.0 so it is the one loaded in memory... they you ask it to load a 4.0 image... it can't work you need to spin a new Runtime instance of the correct version if you want to do that.

The only way to do that may be to Host a second CLR inside your process like explained in Is it possible to host the CLR in a C program? witch became possible with .Net 4.0.

VirtualBlackFox
I was hoping that having a separate AppDomain would allow me to have to different versions of the CLR within the one process. The useLegacyV2RuntimeActivationPolicy attribute implies that with a .NET 4 runtime installed, you can start activitation with .NET 2, and by using the supportedRuntime element, you can say 'load .NET 4 assemblies', as needed. This is exactly what I want to achieve, but unfortunately I'm running into the problem described in the other post. I was hoping that separate AppDomains would allow me to achieve the same thing, with a little more control.
Notre
I edited my answer as .Net 4.0 make loading two CLR instances possible in the same host. Regarding useLegacyV2RuntimeActivationPolicy i think you confuse it with something else as in most cases it only mater with mixed mode assemblies.
VirtualBlackFox
I did use useLegacyV2RuntimeActivationPolicy successfully in 'pure' .NET managed code, in other cases. But in this latest application where I tried to apply it, it had some bad side effects.I am beginning to think it's not possible to resolve my problem in the pure managed .NET case (short of recompiling everything to target .NET 4 runtime), even by using different AppDomains. I've been having this conversation on MSDN forum as well - http://social.msdn.microsoft.com/Forums/en/netfxappcompatprerelease/thread/a181e9b0-9d67-4d3c-80c4-11529196d3bcWould be curious to get your take on it.
Notre
See the above MSDN forum link for confirmation on the fact that AppDomain won't work and also a workaround to the problem.
Notre
A: 

I would be inclined to suspect that the version 2 of the .NET runtime has no clue nor understanding of .NET 4. By the sound and nature of your question, you are dealing with it in the reverse....Have you tried compiling and targetting for .NET 4 to load the .NET 2 runtime library...I would not think it is possible to inter-mix different versions of compiled code (one for .NET 4 and the other for .NET 2) in the same process...

tommieb75
I'm sure you're right that .NET 2 runtime knows nothing about .NET 4 runtime. But, as noted in my earlier comment, there's some "magic" that allows for both to sort of co-exist in the same process, when using the useLegacyV2RuntimeActivationPolicy attribute and supportedRuntime element.I didn't try the reverse, but I guess I'm not clear on how that would help me...
Notre