Chris Crowe's Blog
Ramblings of an IIS MVP ( MVP Since 1997 )

Powered By IIS 7

Search my blog

Some of my readers



My Microsoft Certifications


Dec 15, 1998

Dec 20, 2000

Jan 31, 2001

Jul 22, 2002

Nov 1, 2004

My Microsoft MVP Awards




1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
mvp.support.microsoft.com

August 2006 Entries

This code will allow you to check if there are IIS applications which are configured to use multiple version of the .NET framework.

The code enumerates all the Application Pools and then find all of the applications in that pool. It then checks for the version of the .NET framework which handles the .ASPX file extension.

It saves the unique versions of the .NET Framework found and if it finds multiple versions installed will list all of the applications using that Application Poll and display the path and the version being used. This will allow you to find a potential problem which could be hard to track down normally.

Calling Usage 

cscript CheckForMultipleVersionsOfDotNetFramework.vbs

Example Output

AppPool #1
No applications using this pool!

DefaultAppPool

 Warning multiple version of the .NET framework detected!

 Found references to v1.1.4322
 Found references to v2.0.50727

 //localhost/W3SVC/1/ROO                                           - v1.1.4322
 //localhost/W3SVC/1198258389/ROO                         - v1.1.4322
 //localhost/W3SVC/1280263431/ROO                         - v1.1.4322
 //localhost/W3SVC/1388032739/ROO                         - v1.1.4322
 //localhost/W3SVC/1849151055/ROO                         - v1.1.4322
 //localhost/W3SVC/1957176745/ROO                         - v1.1.4322
 //localhost/W3SVC/4/ROO                                           - v1.1.4322
 //localhost/W3SVC/415889539/ROO                           - v1.1.4322
 //localhost/W3SVC/1/ROOT/Monito                            - v2.0.50727
 //localhost/W3SVC/1/ROOT/Monitorin                        - v1.1.4322
 //localhost/W3SVC/1/ROOT/NetTracke                       - v1.1.4322

ExchangeApplicationPool
Found references to v1.1.4322

ExchangeMobileBrowseApplicationPool
Found references to v1.1.4322

MSSharePointAppPool
Found references to v1.1.4322

MyAppPool1
No applications using this pool!

Source Code

You can download the source code here.

option explicit
dim AppsInPool, objAppPool, index, IISObj, IISPath, Version, pos
Dim Versions(), objAppPools
function FindASPXScriptMapVersion(ScriptMaps)
 Dim pos, ScriptMap
 for pos = lbound(ScriptMaps) to UBOund(ScriptMaps)
   ScriptMap = lcase(ScriptMaps(POS))
   if (left(ScriptMap, 5) = ".aspx") then
    FindASPXScriptMapVersion = mid(ScriptMap, 42)
    FindASPXScriptMapVersion = left(FindASPXScriptMapVersion, _
     instr(FindASPXScriptMapVersion, "\")-1)
    exit function
   end if
 next 
 FindASPXScriptMapVersion = ""
end function
function AddVersion(Version, Path)
 dim Found, pos
 Found = false
 for pos = lbound(Versions) to UBound(Versions)-1
  if (Versions(pos) = Version) then
   Found = true
  end if
 next
 if (Found = false) then
  redim preserve Versions(ubound(Versions)+1)
  Versions(ubound(Versions)-1)= Version
 end if
end function
Set objAppPools = GetObject("IIS://localhost/W3SVC/AppPools")
for each objAppPool in objAppPools
 Redim Versions(0)
 Set objAppPool = GetObject("IIS://localhost/W3SVC/AppPools/" & objAppPool.Name )
 WScript.echo objAppPool.Name 
 AppsInPool= objAppPool.EnumAppsInPool()
 if (ubound(AppsInPool) = -1) then
  WScript.echo vbtab  & "No applications using this pool!"
 else
  for index = lbound(AppsInPool) to UBound(AppsInPool)
   IISPath = AppsInPool(index)
   IISPath = "IIS://localhost/" & mid(IISPath,5, len(IISPath)-5)
   set IISObj = GetObject(IISPath)
   Version = FindASPXScriptMapVersion(IISObj.ScriptMaps)
   call AddVersion(Version, mid(IISPath,5, len(IISPath)-5))
  next
  if (ubound(Versions)> 1) then
   WScript.Echo vbcrlf & vbtab & _
    "Warning multiple version of the .NET framework detected!" & vbcrlf
   
   for pos = lbound(Versions) to ubound(Versions)-1
    WScript.echo vbtab & "Found references to " &  Versions(pos) 
   next
   WScript.echo ""
   for index = lbound(AppsInPool) to UBound(AppsInPool)
    IISPath = AppsInPool(index)
    IISPath = "IIS://localhost/" & mid(IISPath,5, len(IISPath)-5)
    set IISObj = GetObject(IISPath)
    Version = FindASPXScriptMapVersion(IISObj.ScriptMaps)
    WScript.echo vbtab & mid(IISPath,5, len(IISPath)-5) & _
     space(70 - len(IISpath)) & " - " & Version
   next
  else
   for pos = lbound(Versions) to ubound(Versions)-1
    WScript.echo vbtab & "Found references to " &  Versions(pos) 
   next  
  end if
 end if
 WScript.echo ""
next
While trying to upgrade a .NET application from VS.NET 2003 to VS.NET 2005 I found I was getting a problem with creating a MAPI.Session object.

I was getting the following exception:

Searching around in www.google.co.nz and everywhere else I was finding nothing on this error.

I decided that I would simply create a new application and see if it failed.

  • I opened VS.NET 2003
  • I created a new console application
  • I added a reference to "Microsoft CDO 1.21 Library"
  • I added one line of code MAPI.Session sess = new MAPI.Session(); to my Main() routine

I then run the code and it worked fine.

So I repeated the code in VS.NET 2005

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
   class Program
  
{
     
static void Main(string[] args)
      {
          MAPI.
Session sess = new MAPI.Session();
      }
    }
}

I was still getting the exception. I decided to post to the New Zealand .NET User group list that I belong to - see www.dot.net.nz

I got the following response from Alex James

" I don’t know the answer, but one thing I would check is whether different thread types have an effect. I.e. is you app [MTAThread] or [STAThread]

You never know that might be the answer, the default between 2003/2005 maybe different? "

 

I had a look at the code that VS.NET 2003 produced and indeed it has the following attribute above the Main() procedure

      [STAThread]

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
   class Program
  
{
      [STAThread]
      static void Main(string[] args)
      {
          MAPI.
Session sess = new MAPI.Session();
      }
    }
}

I added the attribute to my code and the problem was gone. So obviously the CDO 1.21 library is compiled for STAThreading and not the VS.NET 2005 default which must be MTAThread.

The following is from http://www.sellsbrothers.com/askthewonk/Secure/WhatdoestheSTAThreadattri.htm

The STAThreadAttribute marks a thread to use the Single-Threaded COM Apartment if COM is needed. By default, .NET won't initialize COM at all. It's only when COM is needed, like when a COM object or COM Control is created or when drag 'n' drop is needed, that COM is initialized. When that happens, .NET calls the underlying CoInitializeEx function, which takes a flag indicating whether to join the thread to a multi-threaded or single-threaded apartment.

A multi-threaded apartment (MTA) in COM is more efficient, since any of a number of RPC threads from a pool can be used to handle a request. However, an object on the MTA thread needs to protect itself from multiple threads accessing it at the same time, so that efficiency comes at a cost.

The single-thread apartment (STA) in COM is inherently single-threaded and therefore no additional thread synchronization is needed. The STA is implemented using the thread's Windows message queue, which is how requests to objects on an STA are serialized. Because of how the STA thread is implemented, calls to objects on that thread are serialized with Windows message handling on that thread, making sure that everything, both the COM objects and the underlying windowing objects, e.g. HWNDs, are all synchronized. This is necessary for UI-oriented COM objects, like controls and drag 'n' drop, which must also be synchronized together with the UI.

When COM is needed .NET will call CoInitializeEx, picking the MTA by default because it's more efficient. However, to get the synchronization needed for controls, windows and drag 'n' drop, you need to mark a thread's entry point with the STAThreadAttribute to let .NET know to initialize the UI thread on the STA. All of the VS.NET project templates put that attribute in to make sure you don't forget:

 

 

Steve Schofield ( IIS MVP ) contact me to say that he has released a new version of his IISLogsLite product. The IISLogsLite product is now at version 2 and this product will help administrators handle their IIS Log files.

This is a free product and has more functionality than the previous version of IISLogsLite.

His goal with IISLogsLite 2.0 is to meet most administrators log archiving needs by effectively managing all log files related to Microsoft Internet Information Server 5.0 and 6.0. IISLogsLite 2.0 offers the ability to ZIP files and optionally delete the original log file. 

For more details and to download this free version visit:
http://iislogs.com/help/configure_iislogs_lite_version20.htm

MSDN Library provides access to essential programming information, including technical white papers, software development kits and code samples necessary to develop web services and applications.
 
Size : 450.9 MB - 1729.1 MB depending on the components selected