How to get the "friendly" OS Version Name?

Viewed 92521

I am looking for an elegant way to get the OS version like: "Windows XP Professional Service Pack 1" or "Windows Server 2008 Standard Edition" etc.

Is there an elegant way of doing that?

I am also interested in the processor architecture (like x86 or x64).

12 Answers

You can use WMI to get the product name ("Microsoft® Windows Server® 2008 Enterprise "):

using System.Management;
var name = (from x in new ManagementObjectSearcher("SELECT Caption FROM Win32_OperatingSystem").Get().Cast<ManagementObject>()
                      select x.GetPropertyValue("Caption")).FirstOrDefault();
return name != null ? name.ToString() : "Unknown";

You should really try to avoid WMI for local use. It is very convenient but you pay dearly for it in terms of performance. This is quick and simple:

    public string HKLM_GetString(string path, string key)
    {
        try
        {
            RegistryKey rk = Registry.LocalMachine.OpenSubKey(path);
            if (rk == null) return "";
            return (string)rk.GetValue(key);
        }
        catch { return ""; }
    }

    public string FriendlyName()
    {
        string ProductName = HKLM_GetString(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "ProductName");
        string CSDVersion = HKLM_GetString(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CSDVersion");
        if (ProductName != "")
        {
            return (ProductName.StartsWith("Microsoft") ? "" : "Microsoft ") + ProductName +
                        (CSDVersion != "" ? " " + CSDVersion : "");
        }
        return "";
    }

Why not use Environment.OSVersion? It will also tell you what operating this is - Windows, Mac OS X, Unix, etc. To find out if you are running in 64bit or 32bit, use IntPtr.Size - this will return 4 bytes for 32bit and 8 bytes for 64bit.

Try:

new ComputerInfo().OSVersion;

Output:

Microsoft Windows 10 Enterprise

Note: Add reference to Microsoft.VisualBasic.Devices;

For me below line works which gives me output like: Microsoft Windows 10.0.18362

System.Runtime.InteropServices.RuntimeInformation.OSDescription

It can be used to get information like architecture as well https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.runtimeinformation?view=netframework-4.8

Properties

FrameworkDescription: Returns a string that indicates the name of the .NET installation on which an app is running.

OSArchitecture: Gets the platform architecture on which the current app is running.

OSDescription: Gets a string that describes the operating system on which the app is running.

ProcessArchitecture: Gets the process architecture of the currently running app.

One thing to be careful of is this information is usually localized and will report differently depending on the language of the OS.

You can get a lot of info from WMI look for the Win32_OperatingSystem class

Note that the processor architecture question is complex:

do you mean (higher numers require lower numbers to be true):

  1. The CPU is capable for handling 64bit (in the sense that it supports AMD/intel x64 or Itanium)
  2. The Operating system is 64bit
    • GPR and pointers are 64bits, i.e. XP 64, Vista 64, a 64 bit server release or a 64bit OS for mono
  3. The currently executing process is a 64 bit process (not executing under Wow64 for example)

if you are happy that all 3 must be true then

IntPtr.Size == 8

Indicates that all three are true

Disclosure: After posting this, I realized that I am depending on a Nuget extension method library called Z.ExntensionMethods which contains IndexOf()

using Microsoft.VisualBasic.Devices;

string SimpleOSName()
{
    var name = new ComputerInfo().OSFullName;
    var parts = name.Split(' ').ToArray();
    var take = name.Contains("Server")?3:2;
    return string.Join(" ", parts.Skip(parts.IndexOf("Windows")).Take(take));
}

Faster performance using System.Management;

string SimpleOSName()
{
    var name = new ManagementObjectSearcher("SELECT Caption FROM Win32_OperatingSystem")
        .Get().Cast<ManagementObject>()
        .Select(x => x.GetPropertyValue("Caption").ToString())
        .First();
    var parts = name.Split(' ').ToArray();
    var take = name.Contains("Server")?3:2;
    return string.Join(" ", parts.Skip(parts.IndexOf("Windows")).Take(take));
}

output example:

Windows 7

Windows Server 2008

Related