UPDATE: It seems I have made a mistake and reader Barry Kelly has corrected me in his comment (thanks Barry). Although I haven’t tested all the case it seems that if you have a .NET 1.1 application and you are in an environment that has both 1.1 and 2.0, the application will run on 1.1. If you have only 2.0, it will try to run on 2.0 but may fail due to compatibilities issues (depending on your code and the breaking changes in .NET 2.0). If you want to force your 1.1 application to run only in 1.1 even if you have an environment with just 2.0 you should use the .config file, as specified below.

Again, thanks Barray for pointing that out. Now I know that someone is actually reading what I am writing here 🙂

Hello everyone and welcome to the first post of 2006.

I know I haven’t been posting for a while, but I’ve been a little busy doing some other stuff (and if all goes well you might even hear about it in a couple of months 😉 )

Anyhow, I thought its time to cover some concerning issues that I’ve been seeing around relating to running .NET 2.0 and 1.1 applications side-by-side. First of all, let me just remind everyone that .NET CAN run side-by-side. That’s one of its highly publicized features (the one that’s supposed to stop the DLL Hell).

So, if .NET does know how to run side-by-side why some of the people are having some problems?

Windows Applications
Most people that wrote a Windows application in .NET, be it a Windows Forms application, Console application or a Windows Service, simply put it in some folder and run it. This means that the default .NET behavior of binding to a certain version of the .NET runtime will be to bind this executable with the latest version of the .NET runtime currently installed.

If you wrote your application in .NET 1.1 and you have both .NET 1.1 and 2.0 installed on your machine, when running your application it will try to bind to .NET 2.0.

Now we all know that .NET 2.0, in regards to its Basic Class Library (BCL), is backwards compatible, but there are more than a few breaking changes both in design time and runtime (see list of breaking changes here).

So what can we do?

If you’ll look at the framework’s directory (located at %SYSTEMROOT%\Microsoft.NET\<Framework Version>) you’ll notice that every executable has a .config file near it. The .config file is named just like the executable but adds a .config at the end, so if I’ll have the application ildasm.exe (which disassembles a .NET binary), I’ll find a ildasm.exe.config file near it.

This .config files are called app.config files and they usually holds all kinds of configuration information for an application.

If you’ll open such a app.config file from the framework’s directory you’ll usually see one important statement (you might find some other elements in there that but this is the most important one):

<configuration>
<startup>
<requiredRuntime version=”v1.1.4322″/>
</startup>
</configuration>

This statement tells .NET to bind only to this specified version of the framework. Without this version of the framework installed, this application will not run.

You application may run on other versions of the framework without a problem, if you’ll test it and verifying, so you can add additional “requiredRuntime” elements with additional versions of the runtime (for example 2.0.50727, for .NET 2.0).

If you want to make sure your application runs only with framework v1.1, add an app.config file named in the form of myapp.exe.config (where myapp.exe is the name of your executable) with the above XML snippet inside of it and you are all good to go.

Web Applications
The support in web applications is a bit easier. If you’ll go to IIS, right-click and select properties on you web application, you’ll see that a new tab has been added called ASP.NET. This tab allows you to select the version of the runtime to be used with this application, so all you need to do is simply select the correct version of the runtime (no app.config files needed here).

There is even an added web.config and machine.config editor in this tab, so no more XML hacking and forgetting to add those closing elements tags!

COM Interop
An important problem I’ve encountered is related to COM interop, specifically Com Callable Wrapper (CCW) which allows unmanaged apps to access managed objects exposed as COM objects.

If you’ll take a look at the registry near each registered CCW you’ll see that it has the runtime version that it was created in. It seems as though .NET takes this into account and will not load a CCW that is marked to run in .NET 1.1.

If you have an unmanaged application that uses .NET 1.1 CCWs you’ll probably be forced to add an app.config file to make it work in a machine that has both .NET 1.1. and 2.0.

While Windows Update still doesn’t force everyone to download .NET runtime 2.0, the day is not that far away and everyone writing .NET applications should be well prepared for this scenario, otherwise there is a reasonable chance that some applications may fail simply because no one followed the guidelines for side-by-side (as in side-by-side runtimes) deployment.

  • Barry Kelly

    If you wrote your application in .NET 1.1 and you have both .NET 1.1 and 2.0 installed on your machine, when running your application it will try to bind to .NET 2.0.

    The above statement is incorrect. The application will bind to .NET 1.1. Using a .config to force a requirement of .NET 1.1 is really only necessary if .NET 1.1 might not be installed, and you need to error out in that case, for incompatibility reasons.

    To verify this, run this snippet:

    using System;
    using System.Reflection;

    namespace VerTest
    {
    class Class1
    {
    [STAThread]
    static void Main(string[] args)
    {
    Console.WriteLine(Assembly.GetAssembly(typeof(string)).ImageRuntimeVersion);
    Console.ReadLine();
    }
    }
    }

    While the application is paused, you can examine the loaded DLLs with a tool such as Process Explorer, and verify that only the .NET 1.1 mscorlib and friends are loaded.

  • Matt

    What about if you have an application which references third party components which are compiled against .net 1.1, and you run the host application under .Net 2.?

    Will the third party binaries then run under 2.0? And break if they contain incompatible code?

    Thanks

  • Matt, in most cases 1.1 code (at least the .NET Framework 1.1 code) is compatible with 2.0. There are a few problems that are breaking things but they are relatively small.

    What determines what .NET Runtime is being loaded is the process itself, so if the process itself is 2.0 than the whole code will run under 2.0. If you have at that point a couple of .NET 1.1 assemblies and they have some code which is incompatible with 2.0 the code will break.

  • JC

    We have our main project complied in .net 1.1 using vs 2003 and one small section that is complied using vs 2008 and .net 2.0. When you have iis set to 2.0, it seems you can’t debug the code that is still built in 1.1 using vs 2003 anymore? Is that correct?

  • You cannot use Visual Studio 2003 (which uses .NET 1.1) to debug a .NET 2.0 process.

    You can, however, use Visual Studio 2005 to debug a .NET 2.0 process that runs a .NET 1.1 DLL as long as you have the right symbols.