By Scott Forsyth
November 28, 2003
When ASP.NET v1.1 was released, it became my project to find the best way to support this for our client base at ORCS Web, Inc. We needed to be able to switch versions of the Framework per site as smoothly as possible. Requiring everyone to move to version 1.1 wouldn't work and leaving everyone on version 1.0 wouldn't work either, so we had to have a way to pick and choose and to make the switch without interrupting other sites on the same server.
Is this for you?
Before I go any further, I should mention the reasons why this applies to the average developer as well as the system administrator. Currently there are two released versions of ASP.NET but there are already multiple alpha and beta versions and there will continue to be more. To be able to quickly switch between versions with just a couple clicks and keystrokes makes development and testing against multiple frameworks easy. Granted, aspnet_regiis.exe will accomplish this as I’ll mention below, but it can take over 30 seconds. Imagine being able to immediately switch between Version 1.0, 1.1 and 2.0 (v2.0 is in Alpha at the time of this writing) without setting up multiple sites in IIS. If this interests you, read on because this doesn't just apply to a system administrator.
My 4 objectives were:
1) To be able to update a single site to the new framework
2) To be able to revert back if desired
3) To have an easy way for anyone on our team to be able to do it consistently and quickly
4) To do this without affecting the other sites on the same server
Stating the Obvious
The most obvious way to do this was to use aspnet_regiis.exe supplied with ASP.NET. To use this method I would run "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\aspnet_regiis.exe -s W3SVC/50/ROOT". This would update the Version of the framework for the site with ID 50 and not update the other sites on this server. It has the flexibility required to set this for the whole server, per site or even per sub-folder. The problem I immediately ran into was that both Internet Information Server (IIS) service and Session State would reset, causing every site on the server to be down for up to 2 minutes. Ouch. The strange thing is that the whole server was affected, even when running this against a single site. This met the first 3 objectives. Unfortunately all sites on that server would be affected, blowing the 4th objective out of the water.
The other option I considered is manually changing all the script mappings in the IIS snap-in. To change this manually, select the "Home Directory" tab in IIS and click on the "Configuration" button. The "Mappings" tab has all the mappings. The path to the alternate aspnet_isapi.dll can be changed here. The problem is that this didn't meet the 3rd objective because of the large number of script mappings that had to be manually changed.
Is a better solution possible?
Needless to say, I had to go back to the drawing board to find something that would work better. My initial guess was that doing this from script would be difficult and would probably cause a similar interruption of service to IIS. Fortunately I was wrong on both points. Not only did it turn out to be a simple undertaking but there was zero, yes zero, impact on other sites. Even the site being changed was not affected, other than Session State being reset. That not only met all four of my objectives, it exceeded my expectations.
Using WSH I use an Input box and ask for the server, Site ID (more on the later) and the version to change to. Then ADSI is used to retrieve the current script mappings and do a search-and-replace from the previous version to the new version.
There are a number of ways to obtain the siteID in IIS. My favorite is to go into the properties of the site from the IIS snap-in and click on the "Properties" button in the Logging section. At the bottom, you'll notice a "Log file name". It will start with W3SVC??. For example, it might be W3SVC1 or W3SVC99. It's the number after the W3SVC that counts. (i.e. W3SVC1 is SiteID 1, W3SVC99 is SiteID 99).
At the risk of boring the casual reader I feel I must mention one more thing that was tested. The script mappings are usually inherited from the default mappings for the server. IIS uses its own storage system called the Metabase which is similar in concept to Windows Registry. The first time a site or sub-folder within a site is assigned specific script mappings, it will write its own copy of the script mappings to its area of the metabase. Any new changes to the script mappings will be written against the new copy. ChangeFramework.vbs will work correctly whether or not the custom script mappings are in place.
To use this script, simply save to your computer and double-click. This is freely available to use by all, but I request that you keep the header in place to give credit to both myself and ORCS Web, Inc. There is no warranty whatsoever so if your computer blows up or falls over dead, don't come looking to me for help. But, the disclaimer aside, we've been running this for over 1/2 year on live production servers and it was worked 100% of the time without incident and I personally attest to its stability and trustworthiness.
The script itself can be found at http://www.orcsweb.com/articles/ChangeFramework.zip
It should be pretty obvious by this doesn't install the framework. It simply switches between versions that are already installed on your computer.
Scott Forsyth is Director of IT at ORCS Web, Inc. - a company that provides managed hosting solutions for clients who develop and deploy their applications on Microsoft Windows platforms. Services include shared hosting, dedicated hosting, and webfarm hosting, with specialty in .Net, SQL Server, and architecting highly scalable solutions.