Running Multiple Versions of the Framework Side-by-Side

时间:2022-03-20 17:26:26

Early:

Side-By-Side (a.k.a SBS, or SxS) is the phrase used to refer to the installation of two different versions of the Microsoft Windows .NET Framework on a single client or server machine.  While the 1.0 version of the Framework has been patched twice, these service packs merely replace existing files in the 1.0 Framework with new ones.  The v1.1 Framework is a completely separate runtime that installs on a machine with or without the v1.0 Framework present.

Adopter:

To be clear, side-by-side is not an upgrade.  You can actually have one application using the v1.0 Framework, and another application using the v1.1 Framework, at the same time.

Early:

With no further ado, we need to introduce an occasional guest and personal friend of ours: The Framework. 

The Framework V1.0.3705

I am v1.0.3705, or to you, the v1.0 Framework.  There is no C#, there is no VB, there is no C++, and there is no spoon.

The Framework V1.1.4322

I am v1.1.4322, or to you, the v1.1 Framework.  There is no C#, there is no VB, there is no C++, and there is no spoon.

Early:

Adopter, we forgot to say that we have both Frameworks here with us today.

Adopter:

You know, they sound pretty similar to me.

Early:

Don’t let them hear you say that. 

Running Multiple Versions of the Framework Side-by-Side

While both Frameworks can exist side-by-side, there are some important considerations to take into account if you want your application to be built against a particular version of the Framework and target that version at runtime.

First, it’s important to remember that each particular version of Visual Studio .NET is hard-coded to build applications against a certain Framework.  Visual Studio .NET 2002 will only build applications that compile against v1.0 of the Framework.  Visual Studio .NET 2003 will only build applications that compile against v1.1 of the Framework.  You can deploy configuration files that let a v1.1 app run on the v1.0 Framework, but that’s not the same as building against v1.0.

Adopter:

So if you need to maintain v1.0 and v1.1 applications, you’ll need to install both versions of Visual Studio.  If you’re also maintaining VS 6 applications, you’ll need 3 versions of VS (and about 6 Gigs of disk space).

Early:

It’s somewhat unfortunate that VS 2003 can’t compile against v1.0 of the Framework, but it is true that you can run VS 6, VS 2002, and VS 2003 all at the same time.  It’s also important to remember that if you open a VS 2002 project in VS 2003, it will be permanently upgraded to VS 2003.  For more details, check out our article on what’s new in VS 2003.

Adopter:

If you read the few Microsoft documents on side-by-side, you’ll see that they state an application will run against the version of the Framework that it was compiled on.  This is mostly true.  Let’s take a look at the details:

Windows Forms Applications

Application compiled against

Frameworks Installed

Outcome

1.0 Framework

 

 

1.0 only

Runs against the 1.0 Framework

1.0 and 1.1

Runs by default against the 1.0 Framework.  Can be directed to use the 1.1 Framework instead via a configuration file. 

1.1 only

Runs by default against the 1.1 Framework.  There are no warnings that the app is running against a different version of the Framework than it was compiled against.

1.1 Framework

 

 

1.0 only

Fails to run, with an error, unless a configuration file is included that points to the 1.0 runtime.

1.0 and 1.1

Runs by default against the 1.1 Framework.  Can be directed at the 1.0 Framework via a configuration file.

1.1

Runs against the 1.1 Framework .

Let’s get the Frameworks’ perspective on this.

The Framework V1.0.3705:

I am the Framework.  I run managed code.  I am without flaw.

Early:

It doesn’t sound like v1.0 is really even thinking about this “multiple version” thing.  I guess that makes sense.  After all, when v1.0 was written, there was only one version, so it effectively doesn’t know that v1.1 exists.

The Framework V1.1.4322

I am the Framework.  Only V1.0.3705 came before me.  I am everything that v1.0.3705 was, and more.  They rebuilt me, better than I was before.  I am better, stronger, faster, more secure.  I will run managed code that was built against v1.1.4322.  I will also run managed code that was built against v1.0.3705 if, at runtime, v1.0.3705 is not installed.  I am without flaw.

Early:

Starting to sound a bit like the six million dollar man here.

Adopter:

I like it — the six million dollar Framework.

Adopter:

This is important.  If you compile an app against v1.0 of the Framework, but you run it on a machine that only has v1.1 installed, it will “just run”.  You won’t get any warnings, errors, or anything.  It will just “try” to work. 

Early:

You make it sound like this is a bad thing, even though v1.1 is very compatible with v1.0.  I would guess that 95% of apps won’t just “try” to run, they will run without a problem.  What do you recommend instead?

Adopter:

I don’t think an app should run on v1.1 until it’s been tested on v1.1.  Once it’s been tested, you should be able to ship a configuration file to get the app to work without a recompile, but it just doesn’t seem “trustworthy” to run an app on a Framework that you haven’t tested it with.

Early:

So instead of 5% apps breaking, you’d rather pretend that 100% of apps are already broken?  What sense does that make?  And if you’re that worried about your v1.0 application, you can ship a config file that will prevent it from running on v1.1 (even though it would probably work).

Adopter:

Fine, if it’s an image viewer, who cares if it “just tries to run”.  But what if it’s an accounting package?  No one knew that this would be the default behavior, and there are v1.0 applications that are already deployed.  What do you do about those?  You have to ship a config file as a patch, and hope it gets installed.

Also, this is a real danger.  Window Server 2003 will only include the v1.1 version of the Framework, so it’s quite possible that a v1.0 app will end up running on a box with only v1.1.

Early:

I still think you’re blowing this out of proportion for a good majority of cases.  If you are deploying the v1.0 Framework with your app (as you should), then when your app installs, v1.0 will also install, and your app will use v1.0 at runtime, even if v1.1 is also there.  This problem only arises if people don't take care to deploy the Framework with their app.

Adopter:

What if you’re running an application through no-touch deployment?  Then you typically aren’t deploying the Framework, you’re depending on what’s already there.

Early:

I agree that in a no-touch scenario, redirecting a v1.0 app to the v1.1 Framework can be more of a problem.  If you download a configuration file with your application, though, it's not a problem. 

Adopter:

So, Frameworks, how compatible are you?

The Framework V1.0.3705:

I am the Framework.  I run managed code.  I am without flaw.

The Framework V1.1.4322

I am the Framework.  I can execute your v1.0.3705 applications.  The Framework v1.0.3705 contained imperfections, flaws, or as you call them “bugs”.  Because I contain no bugs, code that you wrote for v1.0.3705, in its imperfection, may perform differently on me, and have a different behavior.  Therefore, I am not 100% compatible.  Instead, I am better, stronger, faster, than what came before.  I am without flaw.

Adopter:

The Framework brings up a good point.  In the past, there were a lot of bugs that Microsoft knew about, but couldn’t fix.  I know that sounds strange, but they knew that people had coded work-arounds, and if they fixed some of the bugs, they would actually break a lot of people’s code.  Now, Microsoft is free to fix any bugs in subsequent versions of the Framework, because you’re always free to continue running on the Framework that you compiled against.  If you have a v1.0 application, it can continue to run on the v1.0 Framework until the end of time (which probably means 5-10 years in computer terms).

Early:

I guess we’d have to look into a crystal ball to figure out if this is really going to be a problem.  Just be aware that if you run a v1.0 application on a box that only contains v1.1, it will quietly try to run.  I think in most cases, it will work fine, but if this worries you, then start shipping config files with your v1.0 applications today.  Also, don’t think that v1.1 will be the last Framework ever released.  You should consider shipping a config file with your v1.1 apps so that they won’t quietly try to run on whatever Framework comes next.

Errors Raised

What if you go the other direction, and try to run a v1.1 application on a machine that only contains v1.0?  By default it won’t run.  Instead, expect the following:

Running Multiple Versions of the Framework Side-by-Side

Notice that it is not the friendliest message.  It would be nice if you were told that the application needs v1.1, and where to go download it, but such is not the case.

Configuration Files

If you want to change the Framework that an application will run against, it is quite easy to create the appropriate configuration files using Visual Studio .NET 2003.  To create configuration files, you go to the Build option in the Properties view for a project.  This option can be accessed simply by right-clicking your project in the Solution Explorer and choosing Properties:

Running Multiple Versions of the Framework Side-by-Side

Running Multiple Versions of the Framework Side-by-Side

It’s also good to note that the configuration files generated by VS 2003 can be used with a v1.0 or v1.1 application, so for the scenario that Adopter was pointing out earlier (pointing out = ranting about J), where you want to insure that a v1.0 application will only run against the v1.0 Framework, you use VS 2003 to generate the following configuration file:

Configuration file targeting v1.0 only:

<?xml version="1.0"?>

<configuration>

<startup>

<supportedRuntime version="v1.0.3705"/>

<requiredRuntime version="v1.0.3705"/>

</startup>

<runtime>

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"

appliesTo="v1.0.3705">

<dependentAssembly>

<assemblyIdentity name="Accessibility"

publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>

<bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535"

newVersion="1.0.3300.0"/>

</dependentAssembly>

<dependentAssembly>

<assemblyIdentity name="cscompmgd" publicKeyToken="b03f5f7f11d50a3a"

culture="neutral"/>

<bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535"

newVersion="7.0.3300.0"/>

</dependentAssembly>

<dependentAssembly>

…(A lot more of these binding redirects)…

</runtime></configuration>

Notice all the <bindingRedirect> tags.  This section is used to tell a v1.0 application only to run on the v1.0 Framework.

To tell a v1.1 application which version of the Framework to use, it’s a lot easier.  You simply place the information in the <startup> section.  This is possible because of a feature known as “unification.”  For an explanation of unification, the Framework can probably describe it best.

The Framework V1.0.3705:

An unhandled exception of type 'Question.UndefinedException' occurred in Unification.Question.  'Unification' is not defined. 

The Framework V1.1.4322:

Unification is a concept that did not exist with v1.0.3705 of the Framework.  Because unification did not exist, your application was required to individually bind to each assembly that was part of v1.0.3705. 

I (v1.1.4322) support unification.  This means that I am considered a single atomic unit, even though I contain many assemblies.  As a result, I can simply be referred to as v1.1.4322, as shown in the <startup> tag.  It is not necessary to bind to each of my assemblies individually.

I am also unique.  You cannot create your own collection of assemblies and unify them so that they are versionable as a unit.  For collections of assemblies that you create, you must bind to each individually.

Adopter:

You can also generate a configuration file that states your application is compatible with either v1.0 or v1.1 of the Framework.  Look at the <startup> section of the following file.  This file says that a minimum of v1.0 is required, but either v1.0 or v1.1 will work.

Configuration file targeting v1.1 and v1.0:

<?xml version="1.0"?>

<configuration>

<startup>

<supportedRuntime version="v1.1.4322"/>

<supportedRuntime version="v1.0.3705"/>

<requiredRuntime version="v1.0.3705"/>

</startup><runtime>

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"

appliesTo="v1.0.3705">

<dependentAssembly>

<assemblyIdentity name="Accessibility"

publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>

<bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535"

newVersion="1.0.3300.0"/>

</dependentAssembly>

 

Early:

Components

I won’t bother with a table when it comes to components and the choices you have for them, because simply put, you don’t have any.  Components are simply dragged along to run against whatever version of the Framework the application wants to run against.  To understand this better, let’s look at a scenario.

You as a component vendor have tested and developed a component against the v1.0 Framework.  It is now deployed and running in some of your customer’s v1.0 Windows applications.  If your customer takes their application and your associated component, and moves it to a machine that only has the v1.1 Framework, the application will “just run” on v1.1, and your components will also have to run against the v1.1 Framework.  An application is either running on v1.0, or v1.1.  There’s no way to have an application using both v1.0 and v1.1 simultaneously.

Adopter:

This works both ways.  If you’ve built a v1.1 component, there’s nothing to prevent a developer from referencing it from a v1.0 application.  In this case, your v1.1 component finds itself running on the v1.0 Framework.  This situation is more dangerous than the reverse, as there’s the potential that your component uses something that doesn’t even exist in v1.0.  If this is the case, expect a “missing method” exception.

ASP.NET

This situation for ASP.NET is (IMHO) really bad.  When you install v1.1 of the Framework, by default, it will upgrade all the web sites to v1.1.  Done inadvertently, this could have serious implications.  This is especially important if you are deploying the Framework with your application (which is a good idea).  In this case, it’s essential that you do not upgrade all the web sites, as this would be completely unexpected behavior.  The correct way to install the Framework, without upgrading existing web sites, is to use the following command:

dotnetfx.exe /q:a /c:"install /noaspupgrade /l /q"

This will perform a quiet install and will leave the ASP.NET sites alone. 

Early:

When you install Visual Studio .NET 2003, it will install the Framework in such a way that all the sites are upgraded.  If you still want some sites to run against v1.0 of the Framework, you can redirect a site back using the following steps:

Open the Visual Studio .NET 2002 command prompt.

  1. Execute the following command:

aspnet_regiis -s w3svc/1/root/MyWebApp

This will re-point the web app to v1.0 of the Framework.  If you wanted to do the reverse (manually point a v1.0 web app at v1.1), you would simply open the Visual Studio .NET 2003 command prompt and run the same command.  Remember, each version of the Framework carries its own complete copy of the Framework assemblies, command line tools, compilers, etc.

Configuration

It’s also important to note that if you have both v1.0 and v1.1 installed, you will have two separate versions of the .NET Configuration Utility.  Changes that you make to permission sets or code groups are version specific.

Adopter:

Summary

To review, here are some key things to keep in mind about Side-By-Side:

Deploy the Framework with your app.  This is the single most important thing you can do to insure that you don’t have to deal with Framework version issues.  Also, when you deploy the Framework with an application, don’t upgrade ASP.NET web sites.

  • 1.0 applications will run on the 1.1 Framework if no configuration file is present to prevent them from doing so.
  • A 1.1 application will fail to execute on a machine with only the 1.0 Framework installed if no configuration file is present to allow it to do so.
  • Components have no life of their own and run against whatever version of the Framework the associated application runs against.  It is not possible to have different components within a single application run against different versions of the Framework.
  • Configuration files can be created by the tools found in Visual Studio .NET 2003.  These configuration files can give explicit instructions for how your application should behave in the presence of v1.0, v1.1, or both.

Finally, I strongly recommend that you test your applications on v1.1 of the Framework.  This Framework truly is more reliable and secure than v1.0.  Once it releases, there’s no reason why your applications shouldn’t leverage it.

Frameworks, any final thoughts?

The Framework V1.0.3705:

I am the Framework.  I run managed code.  I am without flaw.

The Framework V1.1.4322

I am the Framework.  I run managed code.  I am without flaw.

3 Leaf Solutions provides training, consulting, mentoring, and content development services to early adopters of Microsoft technologies.  If you have any questions about 3 Leaf, or comments regarding this article, please don't hesitate to contact Early or Adopter.

You can find more from Early & Adopter in their weblog, or go to the list of 3leaf articles.