192

How can I detect the Windows OS versions in .NET?

What code can I use?

RBT
  • 24,161
  • 21
  • 159
  • 240
Hossein Moradinia
  • 6,116
  • 14
  • 59
  • 85

18 Answers18

347

System.Environment.OSVersion has the information you need for distinguishing most Windows OS major releases, but not all. It consists of three components which map to the following Windows versions:

+------------------------------------------------------------------------------+
|                    |   PlatformID    |   Major version   |   Minor version   |
+------------------------------------------------------------------------------+
| Windows 95         |  Win32Windows   |         4         |          0        |
| Windows 98         |  Win32Windows   |         4         |         10        |
| Windows Me         |  Win32Windows   |         4         |         90        |
| Windows NT 4.0     |  Win32NT        |         4         |          0        |
| Windows 2000       |  Win32NT        |         5         |          0        |
| Windows XP         |  Win32NT        |         5         |          1        |
| Windows 2003       |  Win32NT        |         5         |          2        |
| Windows Vista      |  Win32NT        |         6         |          0        |
| Windows 2008       |  Win32NT        |         6         |          0        |
| Windows 7          |  Win32NT        |         6         |          1        |
| Windows 2008 R2    |  Win32NT        |         6         |          1        |
| Windows 8          |  Win32NT        |         6         |          2        |
| Windows 8.1        |  Win32NT        |         6         |          3        |
+------------------------------------------------------------------------------+
| Windows 10         |  Win32NT        |        10         |          0        |
+------------------------------------------------------------------------------+

For a library that allows you to get a more complete view of the exact release of Windows that the current execution environment is running in, check out this library.

Important note: if your executable assembly manifest doesn't explicitly state that your exe assembly is compatible with Windows 8.1 and Windows 10.0, System.Environment.OSVersion will return Windows 8 version, which is 6.2, instead of 6.3 and 10.0! Source: here.

Update: In .NET 5.0 and later, System.Environment.OSVersion always returns the actual OS version. For more information, see Environment.OSVersion returns the correct operating system version.

Genusatplay
  • 761
  • 1
  • 4
  • 15
Daniel DiPaolo
  • 55,313
  • 14
  • 116
  • 115
  • 13
    This table is at least partially incorrect, **which makes the answer (originally about Win7) incorrect**. People are up-voting without checking to see if it actually works. Win7 does not have a minor of 2 on my machine. I am on Win7 SP1 and my version info shows "Microsoft Windows NT 6.1.7601 Service Pack 1". Looking at Environment.OSVersion gives Build=7601, Major=6, MajorRevision=1, Minor=1, MinorRevision=0, Revision=65536. – scobi Mar 15 '11 at 18:17
  • @Scott huh, thanks for the info, at the time I didn't have a Windows 7 machine to confirm it on but now I can. Found a link that appears to help better and added that instead as well as updated the table. – Daniel DiPaolo Mar 15 '11 at 19:58
  • 4
    I agree with others. This doesn't actually answer the question. Gabe's answer does: http://stackoverflow.com/questions/2819934/detect-windows-7-in-net/2819974#2819974 – Andrew Ensley Mar 22 '11 at 00:43
  • 1
    @Andrew he and I have the same answer for Windows 7, only his doesn't actually address that Windows 2008 looks identical using these particular attributes – Daniel DiPaolo Mar 22 '11 at 00:45
  • I agree that your answer is helpful. I don't mean to be overly critical, but hosseinsinohe specifically asked for code. About 2008 vs 7, you show that they look the same but don't provide any solution. Gabe's answer has code providing what you represented in a table. Of course, hosseinsinohe picked your answer so he/she obviously disagrees. I'm just adding my two cents. – Andrew Ensley Mar 23 '11 at 01:28
  • @Andrew that whole discussion was already covered above, not sure what you were trying to add then – Daniel DiPaolo Mar 23 '11 at 02:31
  • I have upvoted, because this was a good answer, but the section around Server 2008 is misleading. 2K8 is 6.0, and 2K8R2 is 6.1. Source: http://msdn.microsoft.com/en-us/library/ms724832%28v=vs.85%29.aspx – niemiro Jul 14 '11 at 12:18
  • I used the library mentioned above (http://www.codeproject.com/KB/miscctrl/OSVersionInfo.aspx?msg=3449138) for one of my projects. Recently I found out that it stopped returning the Windows version's name (e.g. Windows 7). I've got two systems running on Windows 7 64, and I first noticed this on one of them. A little bit later the other one showed the same symptoms, so I assume it may be down to a patch that was installed. Does anyone else have such problems? The actual error is that "Marshal.SizeOf( typeof( OsVersionInfoEx) ) returns with an error indicating that the buffer size isn't large.. – Gorgsenegger Jul 06 '12 at 07:04
  • ... (continued) enough. But despite using the returned value (or maunally setting larger values) I can't get this to work anymore... – Gorgsenegger Jul 06 '12 at 07:05
  • Sorry, I should correct myself, the error is in the following line in the getter of the Name property if ( GetVersionEx( ref osVersionInfo ) ) – Gorgsenegger Jul 06 '12 at 07:12
  • 4
    Good, now you should update the table with Windows 8 and the latest windows server (2012) as well :) – Davide Piras Nov 08 '12 at 14:38
  • @DavidePiras Done for Windows 8, have no server lying arround to test with :) – GameScripting Mar 06 '13 at 11:52
  • This comment was proposed as an edit by @sauv0168: **EDIT (2015/01/15):** MSDN Operating System Versions can be found [here](http://msdn.microsoft.com/en-ca/library/windows/desktop/ms724832%28v=vs.85%29.aspx). Since this information is updated by Microsoft, it should always be up to date. – laggingreflex Jan 20 '15 at 05:59
  • Windows 8.1 returns minor version as 2. Is there a way to distinguish Windows 8 & 8.1? – AProgrammer Aug 13 '15 at 09:32
  • 1
    More info here explainig why this solution may not work for Windows version beyond 8: https://msdn.microsoft.com/en-us/library/windows/desktop/dn481241(v=vs.85).aspx#base.version_helper_apis – 00seb Apr 12 '17 at 09:14
  • 1
    https://code.msdn.microsoft.com/windowsapps/How-to-determine-the-263b1850 – mja May 23 '17 at 13:42
  • @jjxtra The "important note" at the bottom of the post deals with that. It all due to a bug in Windows where it deliverately lies the version if you don't apply a manifest to the program. See the link for details. – Alejandro May 21 '18 at 18:17
  • @Alejandro hmm. I am sure there is some rationale behind that, but it sure is annoying. – jjxtra May 21 '18 at 19:25
  • @jjxtra Here is [the official excuse](https://msdn.microsoft.com/windows/compatibility/operating-system-version-changes-in-windows-8-1) for introducing this bug. – Alejandro May 21 '18 at 20:12
  • @Alejandro thanks for sharing. Adding a manifest file has fixed it. – jjxtra May 21 '18 at 22:02
  • 2
    This is NOT 100%.. I'm running Windows 10 Pro and it comes back with Windows Vista. When I call the API it shows I'm Win32NT Major Version 6 – Chizl Sep 04 '20 at 19:15
  • @Switch Did you read the important note at the end of the answer? – 41686d6564 stands w. Palestine Nov 24 '20 at 07:28
  • Hello, regarding the Important Note: if your executable assembly manifest doesn't explicitly state that your exe assembly is compatible with Windows 8.1 and Windows 10.0, System.Environment.OSVersion will return Windows 8 version, which is 6.2, instead of 6.3 and 10.0! Source: here. Where and what should I put in the assembly manifest so it correctly detects 10.0 instead of 6.2? – Huzan Toorkey Nov 26 '20 at 09:05
62

I used this when I had to determine various Microsoft Operating System versions:

string getOSInfo()
{
   //Get Operating system information.
   OperatingSystem os = Environment.OSVersion;
   //Get version information about the os.
   Version vs = os.Version;

   //Variable to hold our return value
   string operatingSystem = "";

   if (os.Platform == PlatformID.Win32Windows)
   {
       //This is a pre-NT version of Windows
       switch (vs.Minor)
       {
           case 0:
               operatingSystem = "95";
               break;
           case 10:
               if (vs.Revision.ToString() == "2222A")
                   operatingSystem = "98SE";
               else
                   operatingSystem = "98";
               break;
           case 90:
               operatingSystem = "Me";
               break;
           default:
               break;
       }
   }
   else if (os.Platform == PlatformID.Win32NT)
   {
       switch (vs.Major)
       {
           case 3:
               operatingSystem = "NT 3.51";
               break;
           case 4:
               operatingSystem = "NT 4.0";
               break;
           case 5:
               if (vs.Minor == 0)
                   operatingSystem = "2000";
               else
                   operatingSystem = "XP";
               break;
           case 6:
               if (vs.Minor == 0)
                   operatingSystem = "Vista";
               else if (vs.Minor == 1)
                   operatingSystem = "7";
               else if (vs.Minor == 2)
                   operatingSystem = "8";
               else
                   operatingSystem = "8.1";
               break;
           case 10:
               operatingSystem = "10";
               break;
           default:
               break;
       }
   }
   //Make sure we actually got something in our OS check
   //We don't want to just return " Service Pack 2" or " 32-bit"
   //That information is useless without the OS version.
   if (operatingSystem != "")
   {
       //Got something.  Let's prepend "Windows" and get more info.
       operatingSystem = "Windows " + operatingSystem;
       //See if there's a service pack installed.
       if (os.ServicePack != "")
       {
           //Append it to the OS name.  i.e. "Windows XP Service Pack 3"
           operatingSystem += " " + os.ServicePack;
       }
       //Append the OS architecture.  i.e. "Windows XP Service Pack 3 32-bit"
       //operatingSystem += " " + getOSArchitecture().ToString() + "-bit";
   }
   //Return the information we've gathered.
   return operatingSystem;
}

Source: here

eduardomozart
  • 1,444
  • 15
  • 14
Gabe
  • 49,577
  • 28
  • 142
  • 181
  • What about the getOSArchitecture() method? Error: "The name 'getOSArchitecture' does not exist in the current context." – Lonnie Best May 21 '10 at 21:08
  • @LonnieBest - That is a method that determines whether it's x64 or x86... I didn't use that, just comment it out. – Gabe May 26 '10 at 13:53
  • 2
    `vs.Minor != 0` need not necessarily be `XP` or `7`. It could be any of those server editions which will have the same minor versions.. See here http://msdn.microsoft.com/en-us/library/windows/desktop/ms724832(v=vs.85).aspx – nawfal Aug 07 '13 at 21:19
  • 7
    I have windows 10 here and it returns as windows 8. – Matheus Miranda May 07 '18 at 23:58
  • 6
    @MatheusMiranda - see **Important note** at end of the accepted answer: *"Important note: if your executable assembly manifest doesn't explicitly state that your exe assembly is compatible with Windows 8.1 and Windows 10.0, System.Environment.OSVersion will return Windows 8.0 version ?! which is 6.2, instead of 6.3 and 10.0!!"* – ToolmakerSteve May 08 '18 at 21:59
  • For server versions, check out this link from MS. https://code.msdn.microsoft.com/windowsapps/Sample-to-demonstrate-how-495e69db – daniel.caspers Sep 07 '18 at 18:47
  • Windows 10 doesn't support OSversion, you need to check the registry : `(string)Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\Windows NT\CurrentVersion")?.GetValue("productName");` – Ray Sep 14 '21 at 07:27
32

I use the ManagementObjectSearcher of namespace System.Management

Example:

string r = "";
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem"))
{
    ManagementObjectCollection information = searcher.Get();
    if (information != null)
    {
        foreach (ManagementObject obj in information)
        {
            r = obj["Caption"].ToString() + " - " + obj["OSArchitecture"].ToString();
        }
    }
    r = r.Replace("NT 5.1.2600", "XP");
    r = r.Replace("NT 5.2.3790", "Server 2003");
    MessageBox.Show(r);
}

Do not forget to add the reference to the Assembly System.Management.dll and put the using: using System.Management;

Result:

inserir a descrição da imagem aqui

Documentation

Rovann Linhalis
  • 601
  • 8
  • 14
13

This is a relatively old question but I've recently had to solve this problem and didn't see my solution posted anywhere.

The easiest (and simplest way in my opinion) is to just use a pinvoke call to RtlGetVersion

[DllImport("ntdll.dll", SetLastError = true)]
internal static extern uint RtlGetVersion(out Structures.OsVersionInfo versionInformation); // return type should be the NtStatus enum

[StructLayout(LayoutKind.Sequential)]
internal struct OsVersionInfo
{
    private readonly uint OsVersionInfoSize;

    internal readonly uint MajorVersion;
    internal readonly uint MinorVersion;

    private readonly uint BuildNumber;

    private readonly uint PlatformId;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
    private readonly string CSDVersion;
}

Where Major and Minor version numbers in this struct correspond to the values in the table of the accepted answer.

This returns the correct Windows version number unlike the deprecated GetVersion & GetVersionEx functions from kernel32

IceCreamBoi23
  • 399
  • 5
  • 12
  • 5
    IMO, this is the best answer. Using .Net's Environment.OSVersion requires manipulating your manifest in order to work correctly, and using WMI requires introducing additional dependencies. Simple, straightforward, and uncomplicated. – Andrew Rondeau Feb 11 '20 at 15:28
  • Or better yet use RtlGetNtVersionNumbers()... and no need for any structs. – Mecanik Jul 27 '21 at 04:49
  • Does this also return the correct version if the user has enabled compatibility mode for the current application ? – Elmue Jul 30 '21 at 17:08
  • How can we get `ServicePackMajor`, `ServicePackMinor` and edition of the OS using this mechanism? – RBT Sep 19 '21 at 09:10
  • @RBT Sorry for such a late answer, this function also accepts [OSVERSIONINFOEXW structure](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_osversioninfoexw) (which contain fields you needed), that's also where mistake exists in this answer - `OsVersionInfoSize` must be set before call, so that `RtlGetVersionInfo` is able to distinct between these 2 structure types. – n0ne Dec 03 '21 at 12:44
12

.NET 5

Starting in .NET 5, Environment.OSVersion returns the actual version of the operating system for Windows and macOS.

var version = Environment.OSVersion;
Console.WriteLine(version);

// Microsoft Windows NT 10.0.19044.0

https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/5.0/environment-osversion-returns-correct-version

Older versions of dotnet:

To make sure you get the right version using Environment.OSVersion you should add an app.manifest using Visual Studio and then un-comment the following supportedOS tags:

  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
      <!-- A list of the Windows versions that this application has been tested on
           and is designed to work with. Uncomment the appropriate elements
           and Windows will automatically select the most compatible environment. -->

      <!-- Windows Vista -->
      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />

      <!-- Windows 7 -->
      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />

      <!-- Windows 8 -->
      <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />

      <!-- Windows 8.1 -->
      <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />

      <!-- Windows 10 -->
      <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />

    </application>
  </compatibility>

Then you can use the Environment.OSVersion like so:

var version = Environment.OSVersion;
Console.WriteLine(version);

// Before: Microsoft Windows NT 6.2.9200.0
// After: Microsoft Windows NT 10.0.19044.0

For instance in my machine (Windows 10.0 Build 19044) without the manifest file, the result would be 6.2.9200.0 which is incorrect.

By adding the app.manifest file and un-commenting those tags I will get the right version number which is 10.0.19044.0.

Alternative solution

If you don't like adding app.manifest to your project, you can use OSDescription which is available on .NET Framework 4.7.1+ and .NET Core 1.x+.

// using System.Runtime.InteropServices;
string description = RuntimeInformation.OSDescription;

You can read more about it and supported platforms here.

Shleemypants
  • 2,081
  • 2
  • 14
  • 21
10

You can use this helper class;

using System;
using System.Runtime.InteropServices;

/// <summary>
/// Provides detailed information about the host operating system.
/// </summary>
public static class OSInfo
{
    #region BITS
    /// <summary>
    /// Determines if the current application is 32 or 64-bit.
    /// </summary>
    public static int Bits
    {
        get
        {
            return IntPtr.Size * 8;
        }
    }
    #endregion BITS

    #region EDITION
    private static string s_Edition;
    /// <summary>
    /// Gets the edition of the operating system running on this computer.
    /// </summary>
    public static string Edition
    {
        get
        {
            if (s_Edition != null)
                return s_Edition;  //***** RETURN *****//

            string edition = String.Empty;

            OperatingSystem osVersion = Environment.OSVersion;
            OSVERSIONINFOEX osVersionInfo = new OSVERSIONINFOEX();
            osVersionInfo.dwOSVersionInfoSize = Marshal.SizeOf( typeof( OSVERSIONINFOEX ) );

            if (GetVersionEx( ref osVersionInfo ))
            {
                int majorVersion = osVersion.Version.Major;
                int minorVersion = osVersion.Version.Minor;
                byte productType = osVersionInfo.wProductType;
                short suiteMask = osVersionInfo.wSuiteMask;

                #region VERSION 4
                if (majorVersion == 4)
                {
                    if (productType == VER_NT_WORKSTATION)
                    {
                        // Windows NT 4.0 Workstation
                        edition = "Workstation";
                    }
                    else if (productType == VER_NT_SERVER)
                    {
                        if ((suiteMask & VER_SUITE_ENTERPRISE) != 0)
                        {
                            // Windows NT 4.0 Server Enterprise
                            edition = "Enterprise Server";
                        }
                        else
                        {
                            // Windows NT 4.0 Server
                            edition = "Standard Server";
                        }
                    }
                }
                #endregion VERSION 4

                #region VERSION 5
                else if (majorVersion == 5)
                {
                    if (productType == VER_NT_WORKSTATION)
                    {
                        if ((suiteMask & VER_SUITE_PERSONAL) != 0)
                        {
                            // Windows XP Home Edition
                            edition = "Home";
                        }
                        else
                        {
                            // Windows XP / Windows 2000 Professional
                            edition = "Professional";
                        }
                    }
                    else if (productType == VER_NT_SERVER)
                    {
                        if (minorVersion == 0)
                        {
                            if ((suiteMask & VER_SUITE_DATACENTER) != 0)
                            {
                                // Windows 2000 Datacenter Server
                                edition = "Datacenter Server";
                            }
                            else if ((suiteMask & VER_SUITE_ENTERPRISE) != 0)
                            {
                                // Windows 2000 Advanced Server
                                edition = "Advanced Server";
                            }
                            else
                            {
                                // Windows 2000 Server
                                edition = "Server";
                            }
                        }
                        else
                        {
                            if ((suiteMask & VER_SUITE_DATACENTER) != 0)
                            {
                                // Windows Server 2003 Datacenter Edition
                                edition = "Datacenter";
                            }
                            else if ((suiteMask & VER_SUITE_ENTERPRISE) != 0)
                            {
                                // Windows Server 2003 Enterprise Edition
                                edition = "Enterprise";
                            }
                            else if ((suiteMask & VER_SUITE_BLADE) != 0)
                            {
                                // Windows Server 2003 Web Edition
                                edition = "Web Edition";
                            }
                            else
                            {
                                // Windows Server 2003 Standard Edition
                                edition = "Standard";
                            }
                        }
                    }
                }
                #endregion VERSION 5

                #region VERSION 6
                else if (majorVersion == 6)
                {
                    int ed;
                    if (GetProductInfo( majorVersion, minorVersion,
                        osVersionInfo.wServicePackMajor, osVersionInfo.wServicePackMinor,
                        out ed ))
                    {
                        switch (ed)
                        {
                            case PRODUCT_BUSINESS:
                                edition = "Business";
                                break;
                            case PRODUCT_BUSINESS_N:
                                edition = "Business N";
                                break;
                            case PRODUCT_CLUSTER_SERVER:
                                edition = "HPC Edition";
                                break;
                            case PRODUCT_DATACENTER_SERVER:
                                edition = "Datacenter Server";
                                break;
                            case PRODUCT_DATACENTER_SERVER_CORE:
                                edition = "Datacenter Server (core installation)";
                                break;
                            case PRODUCT_ENTERPRISE:
                                edition = "Enterprise";
                                break;
                            case PRODUCT_ENTERPRISE_N:
                                edition = "Enterprise N";
                                break;
                            case PRODUCT_ENTERPRISE_SERVER:
                                edition = "Enterprise Server";
                                break;
                            case PRODUCT_ENTERPRISE_SERVER_CORE:
                                edition = "Enterprise Server (core installation)";
                                break;
                            case PRODUCT_ENTERPRISE_SERVER_CORE_V:
                                edition = "Enterprise Server without Hyper-V (core installation)";
                                break;
                            case PRODUCT_ENTERPRISE_SERVER_IA64:
                                edition = "Enterprise Server for Itanium-based Systems";
                                break;
                            case PRODUCT_ENTERPRISE_SERVER_V:
                                edition = "Enterprise Server without Hyper-V";
                                break;
                            case PRODUCT_HOME_BASIC:
                                edition = "Home Basic";
                                break;
                            case PRODUCT_HOME_BASIC_N:
                                edition = "Home Basic N";
                                break;
                            case PRODUCT_HOME_PREMIUM:
                                edition = "Home Premium";
                                break;
                            case PRODUCT_HOME_PREMIUM_N:
                                edition = "Home Premium N";
                                break;
                            case PRODUCT_HYPERV:
                                edition = "Microsoft Hyper-V Server";
                                break;
                            case PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT:
                                edition = "Windows Essential Business Management Server";
                                break;
                            case PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING:
                                edition = "Windows Essential Business Messaging Server";
                                break;
                            case PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY:
                                edition = "Windows Essential Business Security Server";
                                break;
                            case PRODUCT_SERVER_FOR_SMALLBUSINESS:
                                edition = "Windows Essential Server Solutions";
                                break;
                            case PRODUCT_SERVER_FOR_SMALLBUSINESS_V:
                                edition = "Windows Essential Server Solutions without Hyper-V";
                                break;
                            case PRODUCT_SMALLBUSINESS_SERVER:
                                edition = "Windows Small Business Server";
                                break;
                            case PRODUCT_STANDARD_SERVER:
                                edition = "Standard Server";
                                break;
                            case PRODUCT_STANDARD_SERVER_CORE:
                                edition = "Standard Server (core installation)";
                                break;
                            case PRODUCT_STANDARD_SERVER_CORE_V:
                                edition = "Standard Server without Hyper-V (core installation)";
                                break;
                            case PRODUCT_STANDARD_SERVER_V:
                                edition = "Standard Server without Hyper-V";
                                break;
                            case PRODUCT_STARTER:
                                edition = "Starter";
                                break;
                            case PRODUCT_STORAGE_ENTERPRISE_SERVER:
                                edition = "Enterprise Storage Server";
                                break;
                            case PRODUCT_STORAGE_EXPRESS_SERVER:
                                edition = "Express Storage Server";
                                break;
                            case PRODUCT_STORAGE_STANDARD_SERVER:
                                edition = "Standard Storage Server";
                                break;
                            case PRODUCT_STORAGE_WORKGROUP_SERVER:
                                edition = "Workgroup Storage Server";
                                break;
                            case PRODUCT_UNDEFINED:
                                edition = "Unknown product";
                                break;
                            case PRODUCT_ULTIMATE:
                                edition = "Ultimate";
                                break;
                            case PRODUCT_ULTIMATE_N:
                                edition = "Ultimate N";
                                break;
                            case PRODUCT_WEB_SERVER:
                                edition = "Web Server";
                                break;
                            case PRODUCT_WEB_SERVER_CORE:
                                edition = "Web Server (core installation)";
                                break;
                        }
                    }
                }
                #endregion VERSION 6
            }

            s_Edition = edition;
            return edition;
        }
    }
    #endregion EDITION

    #region NAME
    private static string s_Name;
    /// <summary>
    /// Gets the name of the operating system running on this computer.
    /// </summary>
    public static string Name
    {
        get
        {
            if (s_Name != null)
                return s_Name;  //***** RETURN *****//

            string name = "unknown";

            OperatingSystem osVersion = Environment.OSVersion;
            OSVERSIONINFOEX osVersionInfo = new OSVERSIONINFOEX();
            osVersionInfo.dwOSVersionInfoSize = Marshal.SizeOf( typeof( OSVERSIONINFOEX ) );

            if (GetVersionEx( ref osVersionInfo ))
            {
                int majorVersion = osVersion.Version.Major;
                int minorVersion = osVersion.Version.Minor;

                switch (osVersion.Platform)
                {
                    case PlatformID.Win32Windows:
                        {
                            if (majorVersion == 4)
                            {
                                string csdVersion = osVersionInfo.szCSDVersion;
                                switch (minorVersion)
                                {
                                    case 0:
                                        if (csdVersion == "B" || csdVersion == "C")
                                            name = "Windows 95 OSR2";
                                        else
                                            name = "Windows 95";
                                        break;
                                    case 10:
                                        if (csdVersion == "A")
                                            name = "Windows 98 Second Edition";
                                        else
                                            name = "Windows 98";
                                        break;
                                    case 90:
                                        name = "Windows Me";
                                        break;
                                }
                            }
                            break;
                        }

                    case PlatformID.Win32NT:
                        {
                            byte productType = osVersionInfo.wProductType;

                            switch (majorVersion)
                            {
                                case 3:
                                    name = "Windows NT 3.51";
                                    break;
                                case 4:
                                    switch (productType)
                                    {
                                        case 1:
                                            name = "Windows NT 4.0";
                                            break;
                                        case 3:
                                            name = "Windows NT 4.0 Server";
                                            break;
                                    }
                                    break;
                                case 5:
                                    switch (minorVersion)
                                    {
                                        case 0:
                                            name = "Windows 2000";
                                            break;
                                        case 1:
                                            name = "Windows XP";
                                            break;
                                        case 2:
                                            name = "Windows Server 2003";
                                            break;
                                    }
                                    break;
                                case 6:
                                    switch (productType)
                                    {
                                        case 1:
                                            name = "Windows Vista";
                                            break;
                                        case 3:
                                            name = "Windows Server 2008";
                                            break;
                                    }
                                    break;
                            }
                            break;
                        }
                }
            }

            s_Name = name;
            return name;
        }
    }
    #endregion NAME

    #region PINVOKE
    #region GET
    #region PRODUCT INFO
    [DllImport( "Kernel32.dll" )]
    internal static extern bool GetProductInfo(
        int osMajorVersion,
        int osMinorVersion,
        int spMajorVersion,
        int spMinorVersion,
        out int edition );
    #endregion PRODUCT INFO

    #region VERSION
    [DllImport( "kernel32.dll" )]
    private static extern bool GetVersionEx( ref OSVERSIONINFOEX osVersionInfo );
    #endregion VERSION
    #endregion GET

    #region OSVERSIONINFOEX
    [StructLayout( LayoutKind.Sequential )]
    private struct OSVERSIONINFOEX
    {
        public int dwOSVersionInfoSize;
        public int dwMajorVersion;
        public int dwMinorVersion;
        public int dwBuildNumber;
        public int dwPlatformId;
        [MarshalAs( UnmanagedType.ByValTStr, SizeConst = 128 )]
        public string szCSDVersion;
        public short wServicePackMajor;
        public short wServicePackMinor;
        public short wSuiteMask;
        public byte wProductType;
        public byte wReserved;
    }
    #endregion OSVERSIONINFOEX

    #region PRODUCT
    private const int PRODUCT_UNDEFINED = 0x00000000;
    private const int PRODUCT_ULTIMATE = 0x00000001;
    private const int PRODUCT_HOME_BASIC = 0x00000002;
    private const int PRODUCT_HOME_PREMIUM = 0x00000003;
    private const int PRODUCT_ENTERPRISE = 0x00000004;
    private const int PRODUCT_HOME_BASIC_N = 0x00000005;
    private const int PRODUCT_BUSINESS = 0x00000006;
    private const int PRODUCT_STANDARD_SERVER = 0x00000007;
    private const int PRODUCT_DATACENTER_SERVER = 0x00000008;
    private const int PRODUCT_SMALLBUSINESS_SERVER = 0x00000009;
    private const int PRODUCT_ENTERPRISE_SERVER = 0x0000000A;
    private const int PRODUCT_STARTER = 0x0000000B;
    private const int PRODUCT_DATACENTER_SERVER_CORE = 0x0000000C;
    private const int PRODUCT_STANDARD_SERVER_CORE = 0x0000000D;
    private const int PRODUCT_ENTERPRISE_SERVER_CORE = 0x0000000E;
    private const int PRODUCT_ENTERPRISE_SERVER_IA64 = 0x0000000F;
    private const int PRODUCT_BUSINESS_N = 0x00000010;
    private const int PRODUCT_WEB_SERVER = 0x00000011;
    private const int PRODUCT_CLUSTER_SERVER = 0x00000012;
    private const int PRODUCT_HOME_SERVER = 0x00000013;
    private const int PRODUCT_STORAGE_EXPRESS_SERVER = 0x00000014;
    private const int PRODUCT_STORAGE_STANDARD_SERVER = 0x00000015;
    private const int PRODUCT_STORAGE_WORKGROUP_SERVER = 0x00000016;
    private const int PRODUCT_STORAGE_ENTERPRISE_SERVER = 0x00000017;
    private const int PRODUCT_SERVER_FOR_SMALLBUSINESS = 0x00000018;
    private const int PRODUCT_SMALLBUSINESS_SERVER_PREMIUM = 0x00000019;
    private const int PRODUCT_HOME_PREMIUM_N = 0x0000001A;
    private const int PRODUCT_ENTERPRISE_N = 0x0000001B;
    private const int PRODUCT_ULTIMATE_N = 0x0000001C;
    private const int PRODUCT_WEB_SERVER_CORE = 0x0000001D;
    private const int PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT = 0x0000001E;
    private const int PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY = 0x0000001F;
    private const int PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING = 0x00000020;
    private const int PRODUCT_SERVER_FOR_SMALLBUSINESS_V = 0x00000023;
    private const int PRODUCT_STANDARD_SERVER_V = 0x00000024;
    private const int PRODUCT_ENTERPRISE_SERVER_V = 0x00000026;
    private const int PRODUCT_STANDARD_SERVER_CORE_V = 0x00000028;
    private const int PRODUCT_ENTERPRISE_SERVER_CORE_V = 0x00000029;
    private const int PRODUCT_HYPERV = 0x0000002A;
    #endregion PRODUCT

    #region VERSIONS
    private const int VER_NT_WORKSTATION = 1;
    private const int VER_NT_DOMAIN_CONTROLLER = 2;
    private const int VER_NT_SERVER = 3;
    private const int VER_SUITE_SMALLBUSINESS = 1;
    private const int VER_SUITE_ENTERPRISE = 2;
    private const int VER_SUITE_TERMINAL = 16;
    private const int VER_SUITE_DATACENTER = 128;
    private const int VER_SUITE_SINGLEUSERTS = 256;
    private const int VER_SUITE_PERSONAL = 512;
    private const int VER_SUITE_BLADE = 1024;
    #endregion VERSIONS
    #endregion PINVOKE

    #region SERVICE PACK
    /// <summary>
    /// Gets the service pack information of the operating system running on this computer.
    /// </summary>
    public static string ServicePack
    {
        get
        {
            string servicePack = String.Empty;
            OSVERSIONINFOEX osVersionInfo = new OSVERSIONINFOEX();

            osVersionInfo.dwOSVersionInfoSize = Marshal.SizeOf( typeof( OSVERSIONINFOEX ) );

            if (GetVersionEx( ref osVersionInfo ))
            {
                servicePack = osVersionInfo.szCSDVersion;
            }

            return servicePack;
        }
    }
    #endregion SERVICE PACK

    #region VERSION
    #region BUILD
    /// <summary>
    /// Gets the build version number of the operating system running on this computer.
    /// </summary>
    public static int BuildVersion
    {
        get
        {
            return Environment.OSVersion.Version.Build;
        }
    }
    #endregion BUILD

    #region FULL
    #region STRING
    /// <summary>
    /// Gets the full version string of the operating system running on this computer.
    /// </summary>
    public static string VersionString
    {
        get
        {
            return Environment.OSVersion.Version.ToString();
        }
    }
    #endregion STRING

    #region VERSION
    /// <summary>
    /// Gets the full version of the operating system running on this computer.
    /// </summary>
    public static Version Version
    {
        get
        {
            return Environment.OSVersion.Version;
        }
    }
    #endregion VERSION
    #endregion FULL

    #region MAJOR
    /// <summary>
    /// Gets the major version number of the operating system running on this computer.
    /// </summary>
    public static int MajorVersion
    {
        get
        {
            return Environment.OSVersion.Version.Major;
        }
    }
    #endregion MAJOR

    #region MINOR
    /// <summary>
    /// Gets the minor version number of the operating system running on this computer.
    /// </summary>
    public static int MinorVersion
    {
        get
        {
            return Environment.OSVersion.Version.Minor;
        }
    }
    #endregion MINOR

    #region REVISION
    /// <summary>
    /// Gets the revision version number of the operating system running on this computer.
    /// </summary>
    public static int RevisionVersion
    {
        get
        {
            return Environment.OSVersion.Version.Revision;
        }
    }
    #endregion REVISION
    #endregion VERSION
}

Sample code is here:

    Console.WriteLine( "Operation System Information" );
    Console.WriteLine( "----------------------------" );
    Console.WriteLine( "Name = {0}", OSInfo.Name );
    Console.WriteLine( "Edition = {0}", OSInfo.Edition );
    Console.WriteLine( "Service Pack = {0}", OSInfo.ServicePack );
    Console.WriteLine( "Version = {0}", OSInfo.VersionString );
    Console.WriteLine( "Bits = {0}", OSInfo.Bits );

I was found at this address : http://www.csharp411.com/wp-content/uploads/2009/01/OSInfo.cs

u8it
  • 3,956
  • 1
  • 20
  • 33
Engin Ardıç
  • 2,459
  • 1
  • 21
  • 19
  • Yes, this code is incomplete for major version 6. It needs a switch on minor version as well as the existing switch on product type. (6.0 and 6.1 mean different things depending on the product type.) – ladenedge May 18 '12 at 18:52
  • 4
    Did you take it from here: http://www.csharp411.com/wp-content/uploads/2009/01/OSInfo.cs? Please give credit.. – nawfal Aug 07 '13 at 13:10
  • 1
    Note that the version edition list is outdated. An updated list can be dervied from the table found at https://msdn.microsoft.com/en-us/library/windows/desktop/ms724358(v=vs.85).aspx – Sean Duggan Jul 12 '17 at 13:34
8

Like R. Bemrose suggested, if you are doing Windows 7 specific features, you should look at the Windows® API Code Pack for Microsoft® .NET Framework.

It contains a CoreHelpers class that let you determine the OS you are currently on (XP and above only, its a requirement for .NET nowaday)

It also provide multiple helper methods. For example, suppose that you want to use the jump list of Windows 7, there is a class TaskbarManager that provide a property called IsPlatformSupported and it will return true if you are on Windows 7 and above.

Pierre-Alain Vigeant
  • 22,635
  • 8
  • 65
  • 101
7

Via Environment.OSVersion which "Gets an System.OperatingSystem object that contains the current platform identifier and version number."

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Gregoire
  • 24,219
  • 6
  • 46
  • 73
5

This question goes back to the Windows XP days and both question and answers have been edited over the years.

The following code works using the .NET Framework and should detect all the versions of Windows 10.

Based on this question and answer - ( How to check windows version in C# on .NET 5.0 console app )

using System;
using Microsoft.Win32;

namespace WindowsVersion
{
    class Version
    {
        static void Main(string[] args)
        {
            string HKLMWinNTCurrent = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion";
            string osName = Registry.GetValue(HKLMWinNTCurrent, "productName", "").ToString();
            string osRelease = Registry.GetValue(HKLMWinNTCurrent, "ReleaseId", "").ToString();
            string osVersion = Environment.OSVersion.Version.ToString();
            string osType = Environment.Is64BitOperatingSystem ? "64-bit" : "32-bit";
            string osBuild = Registry.GetValue(HKLMWinNTCurrent, "CurrentBuildNumber", "").ToString();
            string osUBR = Registry.GetValue(HKLMWinNTCurrent, "UBR", "").ToString();
            Console.WriteLine("OS Name:" + osName);
            Console.WriteLine("OS Release:" + osRelease);
            Console.WriteLine("OS Version:" + osVersion);
            Console.WriteLine("OS Type:" + osType);
            Console.WriteLine("OS Build:" + osBuild);
            Console.WriteLine("OS UBR:" + osUBR);
            Console.WriteLine("Press any key to exit.");
            Console.ReadLine();
        }
    }
}

I have tested it on my computer and the result is as follows.

result

See this Wikipedia article for the list of versions of Windows 10

https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions

Update for Windows 11

According to this link there is currently nowhere in the registry where the Windows product name is held.

https://learn.microsoft.com/en-us/answers/questions/555857/windows-11-product-name-in-registry.html

As a workaround use the following code fragment -

    if (osBuild == "22000")
    {
        osFullName = "Windows 11";
    }

On my computer it reports both Windows 10 and Windows 11.

user10186832
  • 423
  • 1
  • 9
  • 17
  • 2
    This is a full proof answer which gives accurate information in all scenarios. Only thing is that your application might require admin privileges to be able to access the registry. There are some more useful keys over there namely InstallationType (Client/Server), CurrentMajorVersionNumber, CurrentMinorVersionNumber, EditionID (Enterprise, professional, Home, etc.) which anyone can leverage. – RBT Sep 20 '21 at 04:19
4

These all seem like very complicated answers for a very simple function:

public bool IsWindows7 
{ 
    get 
    { 
        return (Environment.OSVersion.Version.Major == 6 &
            Environment.OSVersion.Version.Minor == 1); 
    } 
}
domskey
  • 1,102
  • 11
  • 16
  • 3
    Note: This will also return True for Windows Server 2008 R2 – Matt Wilko Jul 04 '14 at 07:52
  • 3
    Warning: this approach is [not recommended by Microsoft](https://learn.microsoft.com/en-us/dotnet/api/system.environment.osversion?#remarks). – Tobias Aug 17 '20 at 09:16
4
  1. Add reference to Microsoft.VisualBasic.
  2. Include namespace using Microsoft.VisualBasic.Devices;
  3. Use new ComputerInfo().OSFullName

The return value is "Microsoft Windows 10 Enterprise"

nvoigt
  • 75,013
  • 26
  • 93
  • 142
4

Detect OS Version:

    public static string OS_Name()
    {
        return (string)(from x in new ManagementObjectSearcher(
            "SELECT Caption FROM Win32_OperatingSystem").Get().Cast<ManagementObject>() 
            select x.GetPropertyValue("Caption")).FirstOrDefault();
    }
Sheridan
  • 68,826
  • 24
  • 143
  • 183
Vince
  • 41
  • 1
3

One way:

public string GetOSVersion()
{
  int _MajorVersion = Environment.OSVersion.Version.Major;

  switch (_MajorVersion) {
    case 5:
      return "Windows XP";
    case 6:
      switch (Environment.OSVersion.Version.Minor) {
        case 0:
          return "Windows Vista";
        case 1:
          return "Windows 7";
        default:
          return "Windows Vista & above";
      }
      break;
    default:
      return "Unknown";
  }
}

Then simply do wrap a select case around the function.

Jeankowkow
  • 814
  • 13
  • 33
Darknight
  • 2,460
  • 2
  • 22
  • 26
  • 2
    Not relevant to the original post, but if the major version is 5 then you have three possible versions of Windows: 5.0 = Windows 2000, 5.1 = 32-bit Windows XP, 5.2 = Windows Server 2003 or 64-bit Windows XP – Lance U. Matthews May 12 '10 at 23:55
3

The above answers would give me Major version 6 on Windows 10.

The solution that I have found to work without adding extra VB libraries was following:

var versionString = (string)Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows NT\\CurrentVersion")?.GetValue("productName");

I wouldn't consider this the best way to get the version, but the upside this is oneliner no extra libraries, and in my case checking if it contains "10" was good enough.

Matas Vaitkevicius
  • 58,075
  • 31
  • 238
  • 265
1

How about using a Registry to get the name.

"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion" has a value ProductName since Windows XP.

[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentProcess();

[DllImport("kernel32.dll")]
static extern IntPtr GetModuleHandle(string moduleName);

[DllImport("kernel32")]
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

[DllImport("kernel32.dll")]
static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process);

public static bool Is64BitOperatingSystem()
{
    // Check if this process is natively an x64 process. If it is, it will only run on x64 environments, thus, the environment must be x64.
    if (IntPtr.Size == 8)
        return true;
    // Check if this process is an x86 process running on an x64 environment.
    IntPtr moduleHandle = GetModuleHandle("kernel32");
    if (moduleHandle != IntPtr.Zero)
    {
        IntPtr processAddress = GetProcAddress(moduleHandle, "IsWow64Process");
        if (processAddress != IntPtr.Zero)
        {
            bool result;
            if (IsWow64Process(GetCurrentProcess(), out result) && result)
                return true;
        }
    }
    // The environment must be an x86 environment.
    return false;
}

private static string HKLM_GetString(string key, string value)
{
    try
    {
        RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(key);
        return registryKey?.GetValue(value).ToString() ?? String.Empty;
    }
    catch
    {
        return String.Empty;
    }
}

public static string GetWindowsVersion()
{
    string osArchitecture;
    try
    {
        osArchitecture = Is64BitOperatingSystem() ? "64-bit" : "32-bit";
    }
    catch (Exception)
    {
        osArchitecture = "32/64-bit (Undetermined)";
    }
    string productName = HKLM_GetString(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "ProductName");
    string csdVersion = HKLM_GetString(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CSDVersion");
    string currentBuild = HKLM_GetString(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentBuild");
    if (!string.IsNullOrEmpty(productName))
    {
        return
            $"{productName}{(!string.IsNullOrEmpty(csdVersion) ? " " + csdVersion : String.Empty)} {osArchitecture} (OS Build {currentBuild})";
    }
    return String.Empty;
}

If you are using .NET Framework 4.0 or above. You can remove the Is64BitOperatingSystem() method and use Environment.Is64BitOperatingSystem.

Ravi Patel
  • 2,136
  • 3
  • 32
  • 48
0

Reading the WinAPI documentation, I've generated a static class that should properly return the name of the OS version. I added some comments from the WinAPI and links to the documentation.

public static class OsVersionHelper
{

        public static string GetWindowsVersion()
        {
            try
            {
                RtlGetVersion(out OuVersionInfoEXA versionInfo);
                return versionInfo.GetOsVersionInfoToOsName();
            }
            catch (Exception ex)
            {
                Repl.WriteLine(ex.ToString(), ConsoleColor.White, ConsoleColor.Red);
                return string.Empty;
            }
        }

        /// <summary>
        /// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlgetversion
        /// </summary>
        /// <param name="versionInformation">Pointer to either a RTL_OSVERSIONINFOW structure or a RTL_OSVERSIONINFOEXW structure that contains the version information about the currently running operating system. A caller specifies which input structure is used by setting the dwOSVersionInfoSize member of the structure to the size in bytes of the structure that is used.</param>
        /// <returns>RtlGetVersion returns STATUS_SUCCESS.</returns>
        [DllImport("ntdll.dll", SetLastError = true)]
        internal static extern uint RtlGetVersion(out OuVersionInfoEXA versionInformation); // return type should be the NtStatus enum

        /// <summary>
        /// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_osversioninfoexw
        /// </summary>
        /// 
        /// <remarks>
        /// Operating system        Version number  dwMajorVersion dwMinorVersion  Other
        /// Windows 10              10.0*           10              0               OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION
        /// Windows Server 2016     10.0*           10              0               OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION
        /// Windows 8.1             6.3*            6               3               OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION
        /// Windows Server 2012 R2  6.3*            6               3               OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION
        /// Windows 8               6.2             6               2               OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION
        /// Windows Server 2012     6.2             6               2               OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION
        /// Windows 7               6.1             6               1               OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION
        /// Windows Server 2008 R2  6.1             6               1               OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION
        /// Windows Server 2008     6.0             6               0               OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION
        /// Windows Vista           6.0             6               0               OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION
        /// Windows Server 2003 R2  5.2             5               2               GetSystemMetrics(SM_SERVERR2) != 0
        /// Windows Server 2003     5.2             5               2               GetSystemMetrics(SM_SERVERR2) == 0
        /// Windows XP              5.1             5               1               Not applicable
        /// Windows 2000            5.0             5               0               Not applicable
        /// </remarks>

        [StructLayout(LayoutKind.Sequential)]
        internal struct OuVersionInfoEXA
        {
            private readonly uint OsVersionInfoSize;

            internal readonly uint MajorVersion;
            internal readonly uint MinorVersion;

            private readonly uint BuildNumber;

            private readonly uint PlatformId;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
            private readonly string CSDVersion;

            internal readonly ushort wServicePackMajor;
            internal readonly ushort wServicePackMinor;
            internal readonly ushort wSuiteMask;
            internal readonly char wProductType;
            private readonly char wReserved;
        }

        /// <summary>
        /// https://learn.microsoft.com/en-us/windows/win32/api/minidumpapiset/ns-minidumpapiset-minidump_system_info
        /// </summary>
        private const byte VER_NT_WORKSTATION = 1;

        internal static string GetOsVersionInfoToOsName(this in OuVersionInfoEXA info)
        {
            switch (info.MajorVersion)
            {
                case 10:
                    if (info.wProductType == VER_NT_WORKSTATION)
                        return "Windows 10";
                    else
                        return "Windows Server 2016";
                case 6:
                    switch (info.MinorVersion)
                    {
                        case 3:
                            if (info.wProductType == VER_NT_WORKSTATION)
                                return "Windows 8.1";
                            else
                                return "Windows Server 2012 R2";
                        case 2:
                            if (info.wProductType == VER_NT_WORKSTATION)
                                return "Windows 8";
                            else
                                return "Windows Server 2012";

                        case 1:
                            if (info.wProductType == VER_NT_WORKSTATION)
                                return "Windows 7";
                            else
                                return "Windows Server 2008 R2";

                        case 0:
                            return "Windows Server 2008";

                        default:
                            return $"Unknown: {info.MajorVersion}:{info.MinorVersion}";
                    }
                case 5:
                    switch (info.MinorVersion)
                    {
                        case 2:
                            if (GetSystemMetrics(SM_SERVERR2) != 0)
                                return "Windows Server 2003 R2";
                            else
                                return "Windows Server 2003";
                        case 1:
                            return "Windows XP";
                        case 0:
                            return "Windows 2000";
                        default:
                            return $"Unknown: {info.MajorVersion}:{info.MinorVersion}";
                    }
                default:
                    return $"Unknown: {info.MajorVersion}:{info.MinorVersion}";
            }

        }

        /// <summary>
        /// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemmetrics
        /// </summary>
        [DllImport("user32.dll")]
        static extern int GetSystemMetrics(uint smIndex);

        internal const int SM_SERVERR2 = 89;

    }
GLJ
  • 1,074
  • 1
  • 9
  • 17
0

I have a class for this about it.
I wrote this class based on an article on Wikipedia.

You can use this class in your project:

class Windows
{
    public class Info
    {
        public string Name = "";
        public string fullName = "";
        public string UserAgent = "";
        public string Type = "";
        public string codeName = "";
        public string Version = "";
        public string buildNumber = "";
    }

    public static Info GetInfo()
    {
        string HKLMWinNTCurrent = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion";
        string osBuild = Registry.GetValue(HKLMWinNTCurrent, "CurrentBuildNumber", "").ToString();
        string fullName = Registry.GetValue(HKLMWinNTCurrent, "productName", "").ToString();
        string Type = Environment.Is64BitOperatingSystem ? "x64" : "x84";

        string win11 = "Windows 11 version 21H2";
        string win10 = "Windows 10 version ";
        string win81 = "Windows 8.1";
        string win8 = "Windows 8";
        string win7 = "Windows 7";
        string winVista = "Windows Vista";
        string winXP = "Windows XP";
        string winMe = "Windows Me";
        string win98 = "Windows 98";
        string win98_2 = "Windows 98 Second Edition";
        string win2000 = "Windows 2000";

        string v11 = "Windows NT 11";
        string v10 = "Windows NT 10";
        string v81 = "Windows NT 6.3";
        string v8 = "Windows NT 6.2";
        string v7 = "Windows NT 6.1";
        string vVista = "Windows NT 6.0";
        string vXP1 = "Windows NT 5.2";
        string vXP = "Windows NT 5.1";
        string vMe = "Windows NT 4.9";
        string v98 = "Windows NT 4.1";
        string v2000 = "Windows NT 5.0";


        switch (osBuild)
        {
            case "22000":
                return new Info()
                {
                    Name = win11,
                    Version = "21H2",
                    UserAgent = v11,
                    buildNumber = "22000",
                    codeName = "Sun Valley",
                    fullName = fullName,
                    Type = Type
                };
            case "19044":
                return new Info()
                {
                    Name = win10 + "21H2",
                    Version = "21H2",
                    UserAgent = v10,
                    buildNumber = "19044",
                    codeName = "Vibranium",
                    fullName = fullName,
                    Type = Type
                };
            case "19043":
                return new Info()
                {
                    Name = win10 + "21H1",
                    Version = "21H1",
                    UserAgent = v10,
                    buildNumber = "19043",
                    codeName = "Vibranium",
                    fullName = fullName,
                    Type = Type
                };
            case "19042":
                return new Info()
                {
                    Name = win10 + "20H2",
                    Version = "20H2",
                    UserAgent = v10,
                    buildNumber = "19042",
                    codeName = "Vibranium",
                    fullName = fullName,
                    Type = Type
                };
            case "19041":
                return new Info()
                {
                    Name = win10 + "2004",
                    Version = "2004",
                    UserAgent = v10,
                    buildNumber = "19041",
                    codeName = "Vibranium",
                    fullName = fullName,
                    Type = Type
                };
            case "18363":
                return new Info()
                {
                    Name = win10 + "1909",
                    Version = "1909",
                    UserAgent = v10,
                    buildNumber = "18363",
                    codeName = "Vibranium",
                    fullName = fullName,
                    Type = Type
                };
            case "18362":
                return new Info()
                {
                    Name = win10 + "1903",
                    Version = "1903",
                    UserAgent = v10,
                    buildNumber = "18362",
                    codeName = "19H1",
                    fullName = fullName,
                    Type = Type
                };
            case "17763":
                return new Info()
                {
                    Name = win10 + "1809",
                    Version = "1809",
                    UserAgent = v10,
                    buildNumber = "17763",
                    codeName = "Redstone 5",
                    fullName = fullName,
                    Type = Type
                };
            case "17134":
                return new Info()
                {
                    Name = win10 + "1803",
                    Version = "1803",
                    UserAgent = v10,
                    buildNumber = "17134",
                    codeName = "Redstone 4",
                    fullName = fullName,
                    Type = Type
                };
            case "16299":
                return new Info()
                {
                    Name = win10 + "1709",
                    Version = "1709",
                    UserAgent = v10,
                    buildNumber = "16299",
                    codeName = "Redstone 3",
                    fullName = fullName,
                    Type = Type
                };
            case "15063":
                return new Info()
                {
                    Name = win10 + "1703",
                    Version = "1703",
                    UserAgent = v10,
                    buildNumber = "15063",
                    codeName = "Redstone 2",
                    fullName = fullName,
                    Type = Type
                };
            case "14393":
                return new Info()
                {
                    Name = win10 + "1607",
                    Version = "1607",
                    UserAgent = v10,
                    buildNumber = "14393",
                    codeName = "Redstone 1",
                    fullName = fullName,
                    Type = Type
                };
            case "10586":
                return new Info()
                {
                    Name = win10 + "1511",
                    Version = "1511",
                    UserAgent = v10,
                    buildNumber = "10586",
                    codeName = "Threshold 2",
                    fullName = fullName,
                    Type = Type
                };
            case "10240":
                return new Info()
                {
                    Name = win10 + "1507",
                    Version = "NT 10.0",
                    UserAgent = v10,
                    buildNumber = "10240",
                    codeName = "Threshold 1",
                    fullName = fullName,
                    Type = Type
                };
            case "9600":
                return new Info()
                {
                    Name = win81,
                    Version = "NT 6.3",
                    UserAgent = v81,
                    buildNumber = "9600",
                    codeName = "Blue",
                    fullName = fullName,
                    Type = Type
                };
            case "9200":
                return new Info()
                {
                    Name = win8,
                    Version = "NT 6.2",
                    UserAgent = v8,
                    buildNumber = "9200",
                    codeName = win8,
                    fullName = fullName,
                    Type = Type
                };
            case "7601":
                return new Info()
                {
                    Name = win7,
                    Version = "NT 6.1",
                    UserAgent = v7,
                    buildNumber = "7601",
                    codeName = win7,
                    fullName = fullName,
                    Type = Type
                };
            case "6002":
                return new Info()
                {
                    Name = winVista,
                    Version = "NT 6.0",
                    UserAgent = vVista,
                    buildNumber = "6002",
                    codeName = "Longhorn",
                    fullName = fullName,
                    Type = Type
                };
            case "2715":
                return new Info()
                {
                    Name = winXP,
                    Version = "NT 5.2",
                    UserAgent = vXP1,
                    buildNumber = "2715",
                    codeName = "Emerald",
                    fullName = fullName,
                    Type = Type
                };
            case "3790":
                return new Info()
                {
                    Name = winXP,
                    Version = "NT 5.2",
                    UserAgent = vXP1,
                    buildNumber = "3790",
                    codeName = "Anvil",
                    fullName = fullName,
                    Type = Type
                };
            case "2600":
                return new Info()
                {
                    Name = winXP,
                    Version = "NT 5.1",
                    UserAgent = vXP,
                    buildNumber = "2600",
                    codeName = "Symphony, Harmony, Freestyle, Whistler",
                    fullName = fullName,
                    Type = Type
                };
            case "3000":
                return new Info()
                {
                    Name = winMe,
                    Version = "4.9",
                    UserAgent = vMe,
                    buildNumber = "3000",
                    codeName = "Millennium",
                    fullName = fullName,
                    Type = Type
                };
            case "1998":
                return new Info()
                {
                    Name = win98,
                    Version = "4.10",
                    UserAgent = v98,
                    buildNumber = "1998",
                    codeName = "Memphis",
                    fullName = fullName,
                    Type = Type
                };
            case "2222":
                return new Info()
                {
                    Name = win98_2,
                    Version = "4.10",
                    UserAgent = v98,
                    buildNumber = "2222",
                    codeName = "Unknow",
                    fullName = fullName,
                    Type = Type
                };
            case "2195":
                return new Info()
                {
                    Name = win2000,
                    Version = "NT 5.0",
                    UserAgent = v2000,
                    buildNumber = "2195",
                    codeName = "Windows NT 5.0",
                    fullName = fullName,
                    Type = Type
                };

            default:
                return new Info()
                {
                    Name = "Unknow",
                    Version = "Unknow",
                    UserAgent = "Unknow",
                    buildNumber = "Unknow",
                    codeName = "Unknow"
                };
        }
    }
}

and about use this,
var info = Windows.GetInfo();

Console.WriteLine($"Name: {info.Name}");
Console.WriteLine($"fullName: {info.fullName}");
Console.WriteLine($"UserAgent: {info.UserAgent}");
Console.WriteLine($"Type: {info.Type}");
Console.WriteLine($"codeName: {info.codeName}");
Console.WriteLine($"Version: {info.Version}");
Console.WriteLine($"buildNumber: {info.buildNumber}");

Result:
Name: Windows 10 version 21H2
fullName: Windows 10 Enterprise LTSC 2021
UserAgent: Windows NT 10
Type: x64
codeName: Vibranium
Version: 21H2
buildNumber: 19044
Mohebbikhah
  • 53
  • 1
  • 9
-7

Don't over complicate the problem.

string osVer = System.Environment.OSVersion.Version.ToString();

if (osVer.StartsWith("5")) // windows 2000, xp win2k3
{
    MessageBox.Show("xp!");
}
else // windows vista and windows 7 start with 6 in the version #
{
    MessageBox.Show("Win7!");
}
Tisho
  • 8,320
  • 6
  • 44
  • 52
Ben
  • 43
  • 1
  • 1
    Uh, so if it starts with 5 I have a 1 in 3 chance of guessing the OS? – Jimmy D Oct 16 '12 at 17:22
  • 16
    -1 for this because you convert the version to a string and compare it to a number string when you could have just compared the `Major` part of the version. Plus it reports "Win7!" on a Windows NT/Me/98/95 operating system. It also wont cope well with future versions of operating systems – Matt Wilko Jul 18 '13 at 11:57
  • 2
    Textbook example of how _not_ to solve problems like this. – Lightness Races in Orbit Jul 24 '19 at 14:01