What's the foolproof way to tell which version(s) of .NET are installed on a production Windows Server?

.NetWindowsDeployment

.Net Problem Overview


This question is not so much programming related as it is deployment related.

I find myself conversing a lot with the group in my company whose job it is to maintain our production Windows servers and deploy our code on them. For legal and compliance reasons, I do not have direct visibility or any control over the servers so the only way I can tell which version(s) of .NET are installed on any of them is through directions I give to that group.

So far, all of the methods I can think of to tell which version(s) are installed (check for Administrative Tools matching 1.1 or 2.0, check for the entries in the "Add/Remove Programs" list, check for the existence of the directories under c:\Windows\Microsoft.NET) are flawed (I've seen at least one machine with 2.0 but no 2.0 entries under Administrative Tools - and that method tells you nothing about 3.0+, the "Add/Remove Programs" list can get out of sync with reality, and the existence of the directories doesn't necessarily mean anything).

Given that I generally need to know these things are in place in advance (discovering that "oops, this one doesn't have all the versions and service packs you need" doesn't really work well with short maintenance windows) and I have to do the checking "by proxy" since I can't get on the servers directly, what's the foolproof way to tell which version(s) of .NET are installed on a production Windows Server? Preferably some intrinsic way to do so using what the framework installs since it will be quicker and not need some sort of utility to be loaded and also a method which will definitely fail if the frameworks are not properly installed but still have files in place (i.e., there's a directory and gacutil.exe is inded there but that version of the framework is not really "installed")

EDIT: In the absence of a good foolproof intrinsic way to do this built into the Framework(s), does anyone know of a good, lightweight, no-install-required program that can find this out? I can imagine someone could easily write one but if one already exists, that would be even better.

.Net Solutions


Solution 1 - .Net

You should open up IE on the server for which you are looking for this info, and go to this site: <http://www.hanselman.com/smallestdotnet/>

That's all it takes.

The site has a script that looks your browser's "UserAgent" and figures out what version (if any) of the .NET Framework you have (or don't have) installed, and displays it automatically (then calculates the total size if you chose to download the .NET Framework).

Solution 2 - .Net

You can programmatically check the registry and a few other things as per this blog entry.

The registry key to look at is

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\...]

Solution 3 - .Net

Found answer from here:

>Check which .NET Framework version is installed

Open Command Prompt and copy paste one of the below command lines

dir %WINDIR%\Microsoft.Net\Framework\v*

or

dir %WINDIR%\Microsoft.Net\Framework\v* /O:-N /B

Solution 4 - .Net

The Microsoft way is this:

MSDN: How to determine Which .NET Framework Versions Are Installed (which directs you to the following registry key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\...)

If you want foolproof that's another thing. I wouldn't worry about an xcopy of the framework folder. If someone did that I would consider the computer broken.

The most foolproof way would be to write a small program that uses each version of .NET and the libraries that you care about and run them.

For a no install method, PowerBasic is an excellent tool. It creates small no runtime required exe's. It could automate the checks described in the MS KB article above.

Solution 5 - .Net

As per https://stackoverflow.com/questions/139891/whats-the-foolproof-way-to-tell-which-versions-of-net-are-installed-on-a-prod/140037#140037">CodeTrawler's answer, the solution is to enter the following into an explorer window:

> %systemroot%\Microsoft.NET\Framework

Then search for:

> Mscorlib.dll

...and right-click / go to the version tab for each result.

Solution 6 - .Net

http://www.asoft.be/prod_netver.html

Use this "good, lightweight, no-install-required program"

Solution 7 - .Net

The official Microsoft answer on how to do this is in KB article 318785.

Solution 8 - .Net

If the machine that you want to check has the .NET SDK installed, you can use a SDK command prompt and run the program CLRVer.exe.

Solution 9 - .Net

OneTouch deployment will do all the detection and installation of pre-requisites. It's probably best to go with a pre-made solution than trying to roll your own. Trying to roll your own may lead to problems because whatever thing you key on may change with a hotfix or service pack. Likely Microsoft has some heuristic for determining what version is running.

Solution 10 - .Net

The official way to detect .NET 3.0 is described here

http://msdn.microsoft.com/en-us/library/aa480198.aspx

Flawed, because it requires the caller to have registry access permissions.

MSDN also mentions a technique for detecting .NET 3.5 by checking the User Agent string:

http://msdn.microsoft.com/en-us/library/bb909885.aspx

I think Microsoft should have done a better job than this.

Solution 11 - .Net

Also, see the Stack Overflow question How to detect what .NET Framework versions and service packs are installed? which also mentions:

> There is an official Microsoft answer to this question at the knowledge base article [How to determine which versions and service pack levels of the Microsoft .NET Framework are installed][2]

Article ID: 318785 - Last Review: November 7, 2008 - Revision: 20.1 How to determine which versions of the .NET Framework are installed and whether service packs have been applied.

Unfortunately, it doesn't appear to work, because the mscorlib.dll version in the 2.0 directory has a 2.0 version, and there is no mscorlib.dll version in either the 3.0 or 3.5 directories even though 3.5 SP1 is installed ... Why would the official Microsoft answer be so misinformed?

Solution 12 - .Net

To determine your server's support for .NET Framework 4.5 and later versions (tested through 4.5.2): If you don't have Registry access on the server, but have app publish rights to that server, create an MVC 5 app with a trivial controller, like this:

using System.Web.Mvc;

namespace DotnetVersionTest.Controllers
{
    public class DefaultController : Controller
    {
        public string Index()
        {
            return "simple .NET version test...";
        }
    }
}

Then in your Web.config, walk through the desired .NET Framework versions in the following section, changing the targetFramework values as desired:

<system.web>
    <customErrors mode="Off"/>
    <compilation debug="true" targetFramework="4.5.2"/>
    <httpRuntime targetFramework="4.5.2"/>
</system.web>

Publish each target to your server, then browse to <app deploy URL>/Default. If your server supports the target framework, then the simple string will display from your trivial Controller. If not, you'll receive an error like the following:

Example of unsupported .NET 4.5.2 on server

So in this case, my target server doesn't yet support .NET Framework 4.5.2.

Solution 13 - .Net

To get the installed dotnet version,
Create a Console app. Add this class Run that

using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
	public class GetDotNetVersion
	{
		public static void Get45PlusFromRegistry()
        {
            const string subkey = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\";
            using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(subkey))
            {
                if (ndpKey != null && ndpKey.GetValue("Release") != null)
                {
                    Console.WriteLine(".NET Framework Version: " + CheckFor45PlusVersion((int)ndpKey.GetValue("Release")));
                }
                else
                {
                    Console.WriteLine(".NET Framework Version 4.5 or later is not detected.");
                }
            }
        }

        // Checking the version using >= will enable forward compatibility.
        private static string CheckFor45PlusVersion(int releaseKey)
        {
            if (releaseKey >= 394802)
                return "4.6.2 or later";
            if (releaseKey >= 394254)
            {
                return "4.6.1";
            }
            if (releaseKey >= 393295)
            {
                return "4.6";
            }
            if ((releaseKey >= 379893))
            {
                return "4.5.2";
            }
            if ((releaseKey >= 378675))
            {
                return "4.5.1";
            }
            if ((releaseKey >= 378389))
            {
                return "4.5";
            }
            // This code should never execute. A non-null release key shoul
            // that 4.5 or later is installed.
            return "No 4.5 or later version detected";
        }
    }
    // Calling the GetDotNetVersion.Get45PlusFromRegistry method produces 
    // output like the following:
    //       .NET Framework Version: 4.6.1
}

Solution 14 - .Net

It is probably a nasty way to find versions out, but I was always under the impression that all version got installed to <root>:\WINDOWS\Microsoft.NET\Framework.

This provides folders with names such as v2.0.50727 which I believe give detailed version information.

Solution 15 - .Net

Well, like Dean said, you can look at the registry and do what he did. To check if he really has CLR .NET Framework installed, you should look for the MSCorEE.dll file in the %SystemRoot%\System32 directory.

Solution 16 - .Net

Strangely enough, I wrote some code to do this back when 1.1 came out (what was that, seven years ago?) and tweaked it a little when 2.0 came out. I haven't looked at it in years as we no longer manage our servers.

It's not foolproof, but I'm posting it anyway because I find it humorous; in that it's easier to do in .NET and easier still in power shell.

bool GetFileVersion(LPCTSTR filename,WORD *majorPart,WORD *minorPart,WORD *buildPart,WORD *privatePart)
{
    DWORD dwHandle;
    DWORD dwLen = GetFileVersionInfoSize(filename,&dwHandle);
    if (dwLen) {
        LPBYTE lpData = new BYTE[dwLen];
        if (lpData) {
            if (GetFileVersionInfo(filename,0,dwLen,lpData)) {
                UINT uLen;  
                VS_FIXEDFILEINFO *lpBuffer;  
                VerQueryValue(lpData,_T("\\"),(LPVOID*)&lpBuffer,&uLen);  
                *majorPart = HIWORD(lpBuffer->dwFileVersionMS);
                *minorPart = LOWORD(lpBuffer->dwFileVersionMS);
                *buildPart = HIWORD(lpBuffer->dwFileVersionLS);
                *privatePart = LOWORD(lpBuffer->dwFileVersionLS);
                delete[] lpData;
                return true;
            }
        }
    }
    return false;
}

int _tmain(int argc,_TCHAR* argv[])
{
    _TCHAR filename[MAX_PATH];
    _TCHAR frameworkroot[MAX_PATH];
    if (!GetEnvironmentVariable(_T("systemroot"),frameworkroot,MAX_PATH))
        return 1;
    _tcscat_s(frameworkroot,_T("\\Microsoft.NET\\Framework\\*"));
    WIN32_FIND_DATA FindFileData;
    HANDLE hFind = FindFirstFile(frameworkroot,&FindFileData);
    if (hFind == INVALID_HANDLE_VALUE)
        return 2;
    do {
        if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
            _tcslen(FindFileData.cAlternateFileName) != 0) {
            _tcsncpy_s(filename,frameworkroot,_tcslen(frameworkroot)-1);
            filename[_tcslen(frameworkroot)] = 0;
            _tcscat_s(filename,FindFileData.cFileName);
            _tcscat_s(filename,_T("\\mscorlib.dll"));
            WORD majorPart,minorPart,buildPart,privatePart;
            if (GetFileVersion(filename,&majorPart,&minorPart,&buildPart,&privatePart )) {
                _tprintf(_T("%d.%d.%d.%d\r\n"),majorPart,minorPart,buildPart,privatePart);
            }
        }
    } while (FindNextFile(hFind,&FindFileData) != 0);
    FindClose(hFind);
    return 0;
}

Solution 17 - .Net

If you want to find versions prior to .NET 4.5, use code for a console application. Like this:

using System;
using System.Security.Permissions;
using Microsoft.Win32;

namespace findNetVersion
{
    class Program
    {
        static void Main(string[] args)
        {
            using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
                     RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\"))
            {
                foreach (string versionKeyName in ndpKey.GetSubKeyNames())
                {
                    if (versionKeyName.StartsWith("v"))
                    {

                        RegistryKey versionKey = ndpKey.OpenSubKey(versionKeyName);
                        string name = (string)versionKey.GetValue("Version", "");
                        string sp = versionKey.GetValue("SP", "").ToString();
                        string install = versionKey.GetValue("Install", "").ToString();
                        if (install == "") //no install info, must be later version
                            Console.WriteLine(versionKeyName + "  " + name);
                        else
                        {
                            if (sp != "" && install == "1")
                            {
                                Console.WriteLine(versionKeyName + "  " + name + "  SP" + sp);
                            }
                        }
                        if (name != "")
                        {
                            continue;
                        }
                        foreach (string subKeyName in versionKey.GetSubKeyNames())
                        {
                            RegistryKey subKey = versionKey.OpenSubKey(subKeyName);
                            name = (string)subKey.GetValue("Version", "");
                            if (name != "")
                                sp = subKey.GetValue("SP", "").ToString();
                                install = subKey.GetValue("Install", "").ToString();
                            if (install == "") //no install info, ust be later
                                Console.WriteLine(versionKeyName + "  " + name);
                            else
                            {
                                if (sp != "" && install == "1")
                                {
                                    Console.WriteLine("  " + subKeyName + "  " + name + "  SP" + sp);
                                }
                                else if (install == "1")
                                {
                                    Console.WriteLine("  " + subKeyName + "  " + name);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

Otherwise you can find .NET 4.5 or later by querying like this:

private static void Get45or451FromRegistry()
{
    using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
       RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\"))
    {
        int releaseKey = (int)ndpKey.GetValue("Release");
        {
            if (releaseKey == 378389)

                Console.WriteLine("The .NET Framework version 4.5 is installed");

            if (releaseKey == 378758)

                Console.WriteLine("The .NET Framework version 4.5.1  is installed");

        }
    }
}

Then the console result will tell you which versions are installed and available for use with your deployments. This code come in handy, too because you have them as saved solutions for anytime you want to check it in the future.

Solution 18 - .Net

I went into Windows Update & looked at the update history, knowing the server patching is kept up-to-date. I scanned down for .NET updates and it showed me exactly which versions had had updates, which allowed me to conclude which versions were installed.

Solution 19 - .Net

I found this one quite useful. here's the source

enter image description here

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTom KiddView Question on Stackoverflow
Solution 1 - .NetVaibhavView Answer on Stackoverflow
Solution 2 - .NetEd GuinessView Answer on Stackoverflow
Solution 3 - .NetK.DiasView Answer on Stackoverflow
Solution 4 - .NetbruceatkView Answer on Stackoverflow
Solution 5 - .NetJon CageView Answer on Stackoverflow
Solution 6 - .NetthinView Answer on Stackoverflow
Solution 7 - .NetCode TrawlerView Answer on Stackoverflow
Solution 8 - .NetJim DevilleView Answer on Stackoverflow
Solution 9 - .NetOrion AdrianView Answer on Stackoverflow
Solution 10 - .NetJoeView Answer on Stackoverflow
Solution 11 - .NetanonView Answer on Stackoverflow
Solution 12 - .Netdave_k_smithView Answer on Stackoverflow
Solution 13 - .NetMetallic SkeletonView Answer on Stackoverflow
Solution 14 - .NetDeanView Answer on Stackoverflow
Solution 15 - .NetBruno CostaView Answer on Stackoverflow
Solution 16 - .Netuser287466View Answer on Stackoverflow
Solution 17 - .NetRonnie PettyView Answer on Stackoverflow
Solution 18 - .NetKim K.View Answer on Stackoverflow
Solution 19 - .NetMichael BahigView Answer on Stackoverflow