We're often asked how to detect the browser and OS versions via JavaScript running in the Intenet zone. Thanks to Jeremy, Forest, David, and a few other folks on my team for help with these samples. I previously posted a sample that parses the userAgent string and compares it to a finite set of regular expressions to map to a specific IE browser version (including IE8) and then hide content on the page that does not apply to the detected version. The sample below maps a finite set of specific OS and browser combinations to route users to a corresponding page. You will need to add parsing for "windows nt 6.1" for Windows 7.
<script>
function PageInfo(contentCode, osName, osArchitecture, browserName, browserTest) {
this._contentCode = contentCode;
this._osName = osName;
this._osArchitecture = osArchitecture;
this._browserName = browserName;
this._browserTest = browserTest;
}
PageInfo.prototype = {
getContentCode: function() { return this._contentCode;},
getOsName: function() { return this._osName;},
getOsArchitecture: function(){ return this._osArchitecture;},
getBrowserName: function() { return this._browserName;},
browserTest: function(a) {
if(!this._browserTest)return false;
return this._browserTest.test(a);
}
}
function getUserAgentInfo(ua){
for(var k in PageInfoLookup){
if( PageInfoLookup[k].browserTest(ua)){
return PageInfoLookup[k];
}
}
return PageInfoLookup["FailOSIE"];
}
function AutoDetectNav(){
var o = getUserAgentInfo(navigator.userAgent);
return o;
}
var PageInfoLookup = new Object();
PageInfoLookup["2001"] = new PageInfo("2001","Windows Vista","x64","IE8",/^Mozilla\/4\.0.*MSIE 8\.\d+.*Windows NT 6\.0.*((Win64.*x64)|(WOW64))/);
PageInfoLookup["1001"] = new PageInfo("1001","Windows Vista","x64","IE7",/^Mozilla\/4\.0.*MSIE 7\.\d+.*Windows NT 6\.0.*((Win64.*x64)|(WOW64))/);
PageInfoLookup["1003"] = new PageInfo("1003","Windows Vista","x86","IE7",/^Mozilla\/4\.0.*MSIE 7\.\d+.*Windows NT 6\.0/);
PageInfoLookup["2000"] = new PageInfo("2000","Windows Vista","x86","IE8",/^Mozilla\/4\.0.*MSIE 8\.\d+.*Windows NT 6\.0/);
PageInfoLookup["2100"] = new PageInfo("2100","WinXP","x86","IE8",/^Mozilla\/4\.0.*MSIE 8\.\d+.*Windows NT 5\.1/);
PageInfoLookup["2101"] = new PageInfo("2101","WinXP|Win2k3","x64","IE8",/^Mozilla\/4\.0.*MSIE 8\.\d+.*Windows NT 5\.2.*(Win64.*x64)/);
PageInfoLookup["2102"] = new PageInfo("2102","WinXP|Win2k3","x64|IA64","IE8",/^Mozilla\/4\.0.*MSIE 8\.\d+.*Windows NT 5\.2.*WOW64/);
PageInfoLookup["2103"] = new PageInfo("2103","WinXP|Win2k3","IA64","IE8",/^Mozilla\/4\.0.*MSIE 8\.\d+.*Windows NT 5\.2.*Win64.*IA64/);
PageInfoLookup["0100"] = new PageInfo("0100","WinXP","x86","IE7",/^Mozilla\/4\.0.*MSIE 7\.\d+.*Windows NT 5\.1/);
PageInfoLookup["0010"] = new PageInfo("0010","winXP","x86","IE6",/^Mozilla\/4\.0.*MSIE 6\.\d+.*Windows NT 5\.1/);
PageInfoLookup["0101"] = new PageInfo("0101","WinXP|Win2k3","x64","IE7",/^Mozilla\/4\.0.*MSIE 7\.\d+.*Windows NT 5\.2.*(Win64.*x64)/);
PageInfoLookup["0102"] = new PageInfo("0102","WinXP|Win2k3","x64|IA64","IE7",/^Mozilla\/4\.0.*MSIE 7\.\d+.*Windows NT 5\.2.*WOW64/);
PageInfoLookup["0103"] = new PageInfo("0103","WinXP|Win2k3","IA64","IE7",/^Mozilla\/4\.0.*MSIE 7\.\d+.*Windows NT 5\.2.*Win64.*IA64/);
PageInfoLookup["0104"] = new PageInfo("0104","WinXP|Win2k3","x64","IE6",/^Mozilla\/4\.0.*MSIE 6\.\d+.*Windows NT 5\.2.*Win64.*x64/);
PageInfoLookup["0105"] = new PageInfo("0105","WinXP|Win2k3","x64|IA64","IE6",/^Mozilla\/4\.0.*MSIE 6\.\d+.*Windows NT 5\.2.*WOW64/);
PageInfoLookup["0106"] = new PageInfo("0106","WinXP|Win2k3","IA64","IE6",/^Mozilla\/4\.0.*MSIE 6\.\d+.*Windows NT 5\.2.*Win64.*IA64/);
PageInfoLookup["091"] = new PageInfo("091","WIn2k3","x86","IE6",/^Mozilla\/4\.0.*MSIE 6\.\d+.*Windows NT 5\.2/);
PageInfoLookup["092"] = new PageInfo("092","Win2k3","x86","IE7",/^Mozilla\/4\.0.*MSIE 7\.\d+.*Windows NT 5\.2/);
PageInfoLookup["093"] = new PageInfo("093","Win2k3","x86","IE8",/^Mozilla\/4\.0.*MSIE 8\.\d+.*Windows NT 5\.2/);
PageInfoLookup["0001"] = new PageInfo("0001","Win2k","x86","IE6",/^Mozilla\/4\.0.*MSIE 6\.\d+.*Windows NT 5\.0/);
PageInfoLookup["900"] = new PageInfo("900","Win2k","x86","IE5",/^Mozilla\/4\.0.*MSIE 5\.\d+.*Windows NT 5\.0/);
PageInfoLookup["090"] = new PageInfo("090","Win95|Win98|WinNT4","x86","",/^Mozilla\/4\.0.*MSIE \d+\.\d+.*Windows (NT 4\.0|(95|98|ME))/);
PageInfoLookup["FailOSIE"] = new PageInfo("FailOSIE","Unknown","Unknown","Unknown");
</script>
As I indicated in my last post, we continue to release new Fix it solutions in the Knowledge Base (KB). Over the last couple of weeks, the total number of solutions in the KB has jumped from 11 to 32. At the same time, we've also released a couple of Fix it solutions for Windows Error Reporting (WER) issues. If you're a geek, you have probably noticed that all of our Fix it solutions currently in the KB are Windows Installer (MSI) packages. On the other hand, the WER solutions that are available today use an ActiveX control. In the future, we might release both MSI and ActiveX Fix it solutions in KB articles, WER responses, and in other content. So I want to take a minute to provide my geek friends with a few technical details about these two types of Fix it solutions.
For MSI Fix it solutions, a successful installation is logged in the Application Event Log with a message ID of 11707. Here's an example:
Log Name: Application
Source: MsiInstaller
Date: 1/8/2009 3:54:32 PM
Event ID: 11707
Task Category: None
Level: Information
Keywords: Classic
User: UserName
Computer: ComputerName
Description: Product: Disable Microsoft Internet Explorer Script Debugging -- Installation completed successfully.
An unsuccessful MSI installation is logged with a message ID of 11708. Note that unsuccessful might just mean that the fix did not apply because some pre-condition was not met (for example, you tried to run a fix for Windows XP on a Windows Vista computer). Here's an example:
Log Name: Application
Source: MsiInstaller
Date: 1/18/2009 2:41:18 PM
Event ID: 11708
Task Category: None
Level: Information
Keywords: Classic
User: UserName
Computer: ComputerName
Description: Product: Increase Folder View Settings And Customizations Limit -- Installation failed.
Also note that our MSI packages create a restore point, so you can use System Restore to undo. Here's an example screenshot.
For ActiveX Fix it solutions, the FixItClient Class control registers itself in the registry with a CLSID of {588031A3-94BF-4CDD-86D0-939F6F93910F} and places three files in the Downloaded Program Files folder (under %systemroot% by default):
| ActiveX file information |
File name: Fixitcontrol.dll File version: 1.2.10.1 File size: 170,848 bytes MD5 Hash: 872577cbb4b4e8057ac5140e265a9846 SHA-1 Hash: ac444213628b3698e5f0a68f8d7743ca3ebe7bee |
File name: Fixitexecutora.exe File version: 1.2.10.1 File size: 162,144 bytes MD5 Hash: 6ca94386d72558386307ac12bb48c0af SHA-1 Hash: 3f144806c85f691693813beb45f20413ad08abcb |
File name: Fixitshared.dll File version: 1.2.10.1 File size: 97,648 bytes MD5 Hash: e0dfaa1f10b1a0f782e3db18c6904aca SHA-1 Hash: 2caa2c89ba525354fbbcf0820dea057e018465ef |
The ActiveX control also appears as FixItClient Class in the Internet Explorer's Manage Add-ons UI and can be enabled, disabled, or deleted from there. Here's a screenshot.
If you already know all the answers, then you're unlikely to ask interesting questions or discover new things. I was reminded of this again by a blog post a few months ago. It was about an essay in the April 2008 edition of Journal of Cell Science by Martin Schwartz, a professor at the University of Virginia. His catchy title is "The importance of stupidity in scientific research." It's a very old idea actually, and a fundamental part of science.
Richard Feynman put it this way in 1963:
All scientific knowledge is uncertain. This experience with doubt and uncertainty is important. I believe that it is of very great value, and one that extends beyond the sciences. I believe that to solve any problem that has never been solved before, you have to leave the door to the unknown ajar. You have to permit the possibility that you do not have it exactly right. Otherwise, if you have made up your mind already, you might not solve it...
[I]t is of paramount importance, in order to make progress, that we recognize this ignorance and this doubt. Because we have the doubt, we then propose looking in new directions for new ideas. The rate of the development of science is not the rate at which you make observations alone but, much more important, the rate at which you create new things to test...
If we were not able or did not desire to look in any new direction, if we did not have a doubt or recognize ignorance, we would not get any new ideas. There would be nothing worth checking, because we would know what is true.
I expect to use this blog to discuss some things that I think I know, or have discovered, which will focus on my work at Microsoft. However, I also expect to discuss some things that I don't know. So please don't hesitate to tell me if I confuse the two. And feel free to ask questions about anything that I post. The exchange might just create some new things to test!