We recently ran into an interesting issue while running .Net applications compiled with framework 1.1 on machines that have both framework 1.1 and 2.0 installed. The application would run fine on machines with only framework 1.1, but would fail on dynamically loading assemblies using reflection on machines with both versions of framework.
Even though we had a pretty good idea that it got to be the fact that the affected machines had framework 2.0 installed along side with framework 1.1, it took us quite a while to pin-point the exact cause; Visual Studio 2003 did not help debugging and in fact made the problem seemingly more mysterious.
It seemed odd at first when we tried to run the assembly within Visual Studio 2003 IDE. The application did not run, and our break point was not reached (which should be reached because it was the first line of the code). In fact, nothing happened when we pressed the run button. The problem would disappear when we ran the same program within the VS 2003 IDE on a machine with only framework 1.1 installed
Then we noticed that the app.config has the following section:
<startup>
<!– .NET Framework 2.0 –>
<supportedRuntime version=”v2.0.50727″ />
<!– .NET Framework 2.0 Beta 2 –>
<supportedRuntime version=”v2.0.50215″ />
<!– .NET Framework 2.0 Beta 1 –>
<supportedRuntime version=”v2.0.40607″ />
<!– .NET Framework 1.1 –>
<supportedRuntime version=”v1.1.4322″ />
<!– .NET Framework 1.0 –>
<supportedRuntime version=”v1.0.3705″ />
</startup>
And when we moved the v1.1.4332 line to the first (or removed the v2.0.x lines altogether) the problem disappeared.
The solution seems quite simple but clearly there are two issues here. The first one seems to be a backward compatibility issue. It seems that the application should not have errored out at the first place since the 2.0 framework should be backward compatible with 1.1 framework, (well, for the most part it is, but apparently it has some issues when using reflection); The second issue is that when Visual Studio 2003 fails to recognize the version of an assembly, it should issue a warning instead of quit functioning silently. It was the combination of both of these issues that made the matter worse. But I am glad we eventually found where the problem was.