Scott Hanselman

SOLVED: How to Force IIS to load a certain version of the .NET CLR

August 30, '06 Comments [4] Posted in ASP.NET | HttpModule | Web Services
Sponsored By

Micky McQuade turned me on to some code (from MSPSS) to solve my How to FORCE IIS to load a certain version of the CLR/.NET Framework. Greg Menounos also mentioned this solution in the comments.

PROBLEM: As discussed before, you can't use requiredRuntime or any .config changes (any that you ought to) to influence what version of the .NET Framework gets loaded into the IIS worker process. If you are using a .NET object as a COM object within Classic ASP, you'll always get the very latest .NET Framework installed on the machine. The values associated with the (fake) COM Object in the Registry are ignored. NOTE, this problem in with IIS/ASP/ASP.NET. If you're doing other things like calling .NET objects from VB6 Clients or something like that, you can always create a .exe.config and influence things with requiredRuntime like I talked about here.

SOLUTION: The solution is a clever hack. What's the first opportunity to "jump in" and affect IIS? When the ISAPI Filters are loaded. Which ISAPI Filter method is called only once? Why GetFilterVersion(), in fact.

This is one of those 'slap your forehead' solutions because it makes sense when you hear it, but it sounds SO tedious when you come up with it and have to actually sully your nails with C++ again. Sigh, I coded in C++ for 8 years and now not only have I forgotten my ninja skills but I feel slightly dirty when I'm back in there. 

DISCLAIMER: This code of course assumes that there isn't some other higher-priority ISAPI filter doing crazy stuff in .NET. Unlikely, but worth mentioning. It's also totally unsupported, and you didn't get it here. In fact, you don't know where you got it. Who is this? What are you doing here? Move along, nothing to see here! No warranty expressed or implied as I didn't write it. Don't bug Micky or ask MS about it.  There's also no guarantee that this, or anything like this, is a solution for your problem(s).

But it's interesting to read.

BOOL CNativeISAPIFilter::GetFilterVersion(PHTTP_FILTER_VERSION pVer)
{

    LPWSTR pszVer = L"v1.1.4322";

    //or "svr" if you're on a multiproc box and you want the server GC in this process.

    LPWSTR pszFlavor = L"wks";

    ICorRuntimeHost *pHost = NULL;

 

    HRESULT hr = CorBindToRuntimeEx(

        //version

        pszVer,

        // svr or wks

        pszFlavor,

        //domain-neutral"ness" and gc settings - see below.

        STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN | STARTUP_CONCURRENT_GC,

            CLSID_CorRuntimeHost,

        IID_ICorRuntimeHost,

        (void **)&pHost);

 

    // Call default implementation for initialization

    CHttpFilter::GetFilterVersion(pVer);

 

    // Clear the flags set by base class

    pVer->dwFlags &= ~SF_NOTIFY_ORDER_MASK;

 

    // Set the flags we are interested in

    pVer->dwFlags |= SF_NOTIFY_SECURE_PORT | SF_NOTIFY_NONSECURE_PORT |
          SF_NOTIFY_END_OF_NET_SESSION | SF_NOTIFY_END_OF_REQUEST;

 

    // Set Priority

    pVer->dwFlags |= SF_NOTIFY_ORDER_HIGH;

 

    // Load description string

    TCHAR sz[SF_MAX_FILTER_DESC_LEN+1];

 

    ISAPIVERIFY(::LoadString(AfxGetResourceHandle(),

    IDS_FILTER, sz, SF_MAX_FILTER_DESC_LEN));

    _tcscpy(pVer->lpszFilterDesc, sz);

 

    return TRUE;

}

File Attachment: NativeISAPI.zip (558 KB)

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web
Thursday, August 31, 2006 2:47:43 AM UTC
The year or so that I spent writing ISAPI code was a distant faded memory. Thanks for dredging that up. ;-)

Want to bring an NT Server to its knees so you pretty much have to pull the plug to get it to reboot?

Try this:

someFlag = true;

while(someFlag);
{
//do some work
someFlag = false;
}

To Infinity...And BEYOND!!
Friday, September 01, 2006 5:22:50 AM UTC
Why can't you just switch the metadata with the CLR version tab on the VDir?
Anon
Friday, September 01, 2006 5:55:13 AM UTC
Anon - take a look at the post mentioned in the link "as mentioned before." The COM object in the classic ASP page is activating the wrong .NET version and ignoring the CLR version on the VDIR because only ASP.NET cares about that. By the time an ASP.NET page gets hit, it's too late and the wrong CLR has already taken over the process.
Scott Hanselman
Monday, September 04, 2006 5:54:50 AM UTC
very clever! just fyi - we added CLRversion to the AppPool configuration in IIS7, so this will no longer be an issue going forward.
Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.