{"id":69413,"date":"2005-07-12T18:01:00","date_gmt":"2005-07-12T18:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2005\/07\/12\/how-can-i-tell-which-version-of-the-net-framework-is-installed-on-a-computer\/"},"modified":"2005-07-12T18:01:00","modified_gmt":"2005-07-12T18:01:00","slug":"how-can-i-tell-which-version-of-the-net-framework-is-installed-on-a-computer","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-tell-which-version-of-the-net-framework-is-installed-on-a-computer\/","title":{"rendered":"How Can I Tell Which Version of the .NET Framework is Installed on a Computer?"},"content":{"rendered":"<p><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"> \n<P>Hey, Scripting Guy! How can I tell which version of the .NET Framework is installed on a computer?<BR><BR>&#8212; MW<\/P><IMG border=\"0\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" height=\"5\"><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\"><A href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><IMG class=\"farGraphic\" title=\"Script Center\" border=\"0\" alt=\"Script Center\" align=\"right\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" height=\"288\"><\/A> \n<P>Hey, MW. You know, every now and then people say to us, \u201cWow, you guys write a daily column about system administration scripting; you must be really smart.\u201d We wish. The truth is, we write a daily column about system administration because we <I>aren\u2019t<\/I> smart. When we first began this column (our one-year anniversary is fast approaching) we assumed that it would be easy: people would ask us questions like, \u201cHow do I display information in a message box?\u201d and we\u2019d respond by writing a script like this:<\/P><PRE class=\"codeSample\">Msgbox &#8220;Here is information in a message box.&#8221;\n<\/PRE>\n<P>The rest of the day would then be free for playing Internet poker and watching baseball. Sweet.<\/P>\n<P>What we failed to take into account, though, is the fact that while Windows is an excellent platform for system administration scripting it\u2019s not without its weaknesses. And, needless to say, those weak spots represent the things nearly everyone asks questions about. (Come on, doesn\u2019t <I>anyone<\/I> want to know how to display information in a message box?) As a result, we have to spend a lot of time researching various problems, trying out possible solutions, and, well, <I>working<\/I>. Meanwhile, the World Series of Poker goes on without us.<\/P>\n<TABLE id=\"EGD\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P><B>Scripting Guys Opinion<\/B>. No, we do not believe that the World Series of Poker should be seen on ESPN; the same goes for the National Spelling Bee, the X Games, the NBA, and other pseudo-sports. (We have nothing against these events, but come on: not at the expense of baseball or college basketball.) Of course, if ESPN is willing to broadcast Scripting Week 3, well, we\u2019re willing to reconsider our position. ESPN, we\u2019re waiting to hear from you.<\/P>\n<P><B>Editor\u2019s Note<\/B>. Now for the legal stuff: The opinions expressed here are not necessarily the opinions of the Microsoft Corporation or anyone else affiliated with Microsoft, etc. etc. As a matter of fact, not all of the Scripting Guys even agree on what a \u201csport\u201d is. (But really, poker and spelling?)<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>MW\u2019s question about the .NET Framework is a good example of the dilemma we sometimes face. It\u2019s very important to know which version of the .NET Framework is installed on a computer, especially when you\u2019re working with custom applications written in-house; the Scripting Guys know from painful experience that custom applications often require a very specific version of the .NET Framework. Any version earlier &#8211; or later &#8211; and the application might not run. <\/P>\n<P>Because of that you might think there\u2019s a very quick, easy way to determine which version (or versions) of the .NET Framework is installed on a computer. Well, if there is, we couldn\u2019t find it: we were unable to locate a COM object or a specific registry key that could tell us, once and for all, which version is installed on a computer. The best we could do was this brute force method, a method which is accompanied by a caveat we\u2019ll talk about momentarily. First let\u2019s take a look at the script:<\/P><PRE class=\"codeSample\">strComputer = &#8220;.&#8221;<\/p>\n<p>Set objWMIService = GetObject(&#8220;winmgmts:\\\\&#8221; &amp; strComputer &amp; &#8220;\\root\\cimv2&#8221;)\nSet colItems = objWMIService.ExecQuery(&#8220;Select * from Win32_Product&#8221;)<\/p>\n<p>For Each objItem in colItems\n    If InStr(objItem.Name, &#8220;Microsoft .NET Framework&#8221;) &gt; 0 Then\n        Wscript.Echo objItem.Version\n    End If\nNext\n<\/PRE>\n<P>As you can see, the script itself is pretty simple. We begin by connecting to the WMI service and then use the <B>ExecQuery<\/B> method to retrieve a collection of the all the instances of the <B>Win32_Product<\/B> class. Win32_Product is designed to retrieve information about all the software on a computer that was installed using Windows Installer (i.e., a .MSI file). Win32_Product is not foolproof &#8211; it sometimes misses an application that really <I>was<\/I> installed using Windows Installer &#8211; but it seems to have no problem identifying most major software programs, including the .NET Framework.<\/P>\n<P>After issuing the query we set up a For Each loop to cycle through the collection of software products installed using .MSI files. Inside this loop we use this line of code and the <B>InStr<\/B> function to see if the application name includes the string <I>Microsoft .NET Framework<\/I>:<\/P><PRE class=\"codeSample\">If InStr(objItem.Name, &#8220;Microsoft .NET Framework&#8221;) &gt; 0 Then\n<\/PRE>\n<TABLE id=\"EME\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\"><B>Note<\/B>. We called this a brute force method because we\u2019re returning all the installed software products and laboriously checking each name. We could have used the <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/topics\/win2003\/like.mspx\" target=\"_blank\"><B>LIKE operator<\/B><\/A> to return <I>only<\/I> software that has the string <I>Microsoft .NET Framework<\/I> somewhere in its name. Unfortunately, though, the LIKE operator is found only on Windows XP and Windows Server 2003. Because of that, we went with the brute force method to ensure that the script would also run on Windows 2000.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>All we\u2019re doing here is passing InStr two parameters: objItem.Name (a variable which contains the name of the application) and our target string (Microsoft .NET Framework). If our target string cannot be found in objItem.Name, then the return value of InStr will be 0; if the target string <I>can<\/I> be found, then InStr will be a value other than 0. To be specific, InStr will equal the character position where our target string begins. For example, suppose objItem.Name equals this:<\/P><PRE class=\"codeSample\">The Microsoft .NET Framework Version 2.0\n<\/PRE>\n<P>In that case, InStr will equal 5, because the string <I>Microsoft .NET Framework<\/I> begins at the fifth character. If InStr is greater than 0 we echo the <B>Version<\/B> property of the application; in other words, we\u2019ll get back information similar to this:<\/P><PRE class=\"codeSample\">1.1.4322\n<\/PRE>\n<P>And, of course, if we have multiple version of the .NET Framework installed we\u2019d get back more than one version number.<\/P>\n<P>As you can see, this actually works quite nicely. So what\u2019s the problem? Well, there are really two issues. For one, this <I>can<\/I> be a little slow: the Win32_Product class is no speed demon, and it could take 30 seconds or so before you get any information back (depending in large part on how many applications are installed on your computer). More important, the Win32_Product class is not installed by default on Windows Server 2003. If you want to run the script against a Windows 2003 machine you\u2019ll need to do the following:<\/P>\n<TABLE class=\"numberedList\" border=\"0\" cellSpacing=\"0\" cellPadding=\"0\">\n<TBODY>\n<TR vAlign=\"top\">\n<TD class=\"listNumber\" noWrap align=\"right\">\n<P>1.<\/P><\/TD>\n<TD>\n<P>In Add or Remove Programs, click <B>Add\/Remove Windows Components<\/B>.<\/P><\/TD><\/TR>\n<TR vAlign=\"top\">\n<TD class=\"listNumber\" noWrap align=\"right\">\n<P>2.<\/P><\/TD>\n<TD>\n<P>In the <B>Windows Components Wizard<\/B>, select <B>Management and Monitoring Tools<\/B> and then click <B>Details<\/B>.<\/P><\/TD><\/TR>\n<TR vAlign=\"top\">\n<TD class=\"listNumber\" noWrap align=\"right\">\n<P>3.<\/P><\/TD>\n<TD>\n<P>In the <B>Management and Monitoring Tools<\/B> dialog box, select <B>WMI Windows Installer Provider<\/B> and then click <B>OK<\/B>.<\/P><\/TD><\/TR>\n<TR vAlign=\"top\">\n<TD class=\"listNumber\" noWrap align=\"right\">\n<P>4.<\/P><\/TD>\n<TD>\n<P>Click <B>Next<\/B>.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<P>Yes, kind of a hassle, but probably worth it. After all, the Win32_Product class can be used to get at more information than just the version of the .NET Framework installed on a computer.<\/P>\n<P>Oh, and did we mention that we use this line of code to display information in a message box?<\/P><PRE class=\"codeSample\">Wscript.Echo objItem.Version\n<\/PRE>\n<P>Then again, if you\u2019re running under CScript, information will display in the command window instead of a message box. OK, so maybe it isn\u2019t so bad that people don\u2019t ask us questions like, \u201cHow do I display information in a message box?\u201d Even <I>that<\/I> isn\u2019t as simple as we thought it was.<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I tell which version of the .NET Framework is installed on a computer?&#8212; MW Hey, MW. You know, every now and then people say to us, \u201cWow, you guys write a daily column about system administration scripting; you must be really smart.\u201d We wish. The truth is, we write a [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[66,31,3,5],"class_list":["post-69413","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-net-framework","tag-operating-system","tag-scripting-guy","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I tell which version of the .NET Framework is installed on a computer?&#8212; MW Hey, MW. You know, every now and then people say to us, \u201cWow, you guys write a daily column about system administration scripting; you must be really smart.\u201d We wish. The truth is, we write a [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/69413","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=69413"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/69413\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=69413"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=69413"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=69413"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}