Click here to Skip to main content
15,898,901 members
Articles / Desktop Programming / Windows Forms

Getting Operating System Version Info - Even for Windows 10!

,
Rate me:
Please Sign up or sign in to vote.
4.92/5 (75 votes)
20 Nov 2012CPOL4 min read 389.2K   19.7K   115   114
Get the operating system version and edition, updated with Windows 10

 

OSVersionInfo

Introduction

I was looking for a way to determine the version of the operating system my program was running under. When I Googled it, I got a lot of code hits, but they all had the same problem: They were not updated for Windows 7. 

Also, all of them had the same two shortcomings:

  1. They didn't include all available Windows editions (especially the absence of "Professional" bothered me as that is the operating system edition I normally use)
  2. I wanted to know if the operating system was 32 bit or 64 bit, and none of the solutions I found correctly determined that. Much more on that later...

Background

I found this article http://www.csharp411.com/determine-windows-version-and-edition-with-c/ and that was in my opinion the best and most updated version. So I decided to simply amend that code and add the things that were missing.

Please note: ALL CREDIT FOR THE ORIGINAL CODE GOES TO "TIMM", THE AUTHOR OF THE ABOVEMENTIONED ARTICLE...

Changes Made By Me

  1. I added "Windows 7" and "Windows Server 2008 R2" to the detection scheme.
  2. I added all the missing Windows editions I could find.
  3. Completely rewrote the 32/64 bit detection code.

Using the Code

The class I came up with is very easy to use. Just include the CS file in your project (or compile it to a DLL for use in your VB project), and query the properties like this:

C#
StringBuilder sb = new StringBuilder(String.Empty);
sb.AppendLine("Operation System Information");
sb.AppendLine("----------------------------");
sb.AppendLine(String.Format("Name = {0}", OSVersionInfo.Name));
sb.AppendLine(String.Format("Edition = {0}", OSVersionInfo.Edition));
if (OSVersionInfo.ServicePack!=string.Empty)
   sb.AppendLine(String.Format("Service Pack = {0}", OSVersionInfo.ServicePack));
else
   sb.AppendLine("Service Pack = None");
sb.AppendLine(String.Format("Version = {0}", OSVersionInfo.VersionString));
sb.AppendLine(String.Format("ProcessorBits = {0}", OSVersionInfo.ProcessorBits));
sb.AppendLine(String.Format("OSBits = {0}", OSVersionInfo.OSBits));
sb.AppendLine(String.Format("ProgramBits = {0}", OSVersionInfo.ProgramBits));

textBox1.Text = sb.ToString();

Points of Interest

The big problem with this was actually the detection of whether or not your OPERATING SYSTEM is 32 or 64 bits. As mentioned, I found a lot of suggestions to how this could be detected, but none of them worked properly. For those who are interested and for the sake of learning/sharing information, I'll list the different suggestions here:

  1. Using the IntPtr size

    The most popular method seems to be variations on this:

    C#
    return IntPtr.Size * 8;

    But this doesn't actually return the Bit architecture of the OS, it returns the bit value for the running program. So for programs running in 32 bit mode on 64 bit Windows, the above code will return 32.

  2. Using the 'PROCESSOR_ARCHITECTURE' Environment variable:
    C#
    string pa = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE");
    return ((String.IsNullOrEmpty(pa) || String.Compare(pa, 0,
        "x86", 0, 3, true) == 0) ? 32 : 64);

    This is actually very misleading, because the result of this is exactly the same as version 1: It doesn't return the PROCESSOR bit architecture as the name says, but the bit architecture of the running program. For programs running in 32 bit mode on 64 bit Windows, the above code will ALSO return 32.

  3. Using PInvoke and GetSystemInfo

    Please note: To keep the article at a reasonable length, I'm not including the Structure declarations and the PInvoke API declarations... They can be found in the source code.

    C#
    ProcessorArchitecture pbits = ProcessorArchitecture.Unknown;
    try
    {
        SYSTEM_INFO l_System_Info = new SYSTEM_INFO();
        GetSystemInfo(ref l_System_Info);
        switch (l_System_Info.uProcessorInfo.wProcessorArchitecture)
        {
            case 9: // PROCESSOR_ARCHITECTURE_AMD64
                pbits = ProcessorArchitecture.Bit64;
                break;
    
            case 6: // PROCESSOR_ARCHITECTURE_IA64
                pbits = ProcessorArchitecture.Itanium64;
                break;
    
            case 0: // PROCESSOR_ARCHITECTURE_INTEL
                pbits = ProcessorArchitecture.Bit32;
                break;
    
            default: // PROCESSOR_ARCHITECTURE_UNKNOWN
                pbits = ProcessorArchitecture.Unknown;
                break;
        }
    }
    catch
    {
        Ignore 
    }
    return pbits;

    Once again, I was disappointed. This code - despite the presence of the processor specific flags - ALSO returned the bits of the running program, not the OS and not the processor.

  4. Using PInvoke and GetNativeSystemInfo

    I read somewhere that the above was not to be trusted (as I had already discovered), and that you should use the GetNativeSystemInfo API instead.

    The code is exactly the same as the above, but GetSystemInfo is replaced by GetNativeSystemInfo, and the same in the API declaration.

    NOW I got another result. But alas, it seemed that this API actually returns the bit architecture of the processor itself. And I was interested in the OS bit architecture. You can easily have a 32 bit windows version running on a 64 bit processored machine.

    So I was still not done.

    After A LOT of research, I found the method I decided to use in the class:

  5. A combination of IntPtr.Size and IsWow64Process:
    C#
    static public SoftwareArchitecture OSBits
    {
        get
        {
            SoftwareArchitecture osbits = SoftwareArchitecture.Unknown;
    
            switch (IntPtr.Size * 8)
            {
                case 64:
                    osbits = SoftwareArchitecture.Bit64;
                    break;
    
                case 32:
                    if (Is32BitProcessOn64BitProcessor())
                        osbits = SoftwareArchitecture.Bit64;
                    else
                        osbits = SoftwareArchitecture.Bit32;
                    break;
    
                default:
                    osbits = SoftwareArchitecture.Unknown;
                    break;
            }
    
            return osbits;
        }
    }
    
    private static IsWow64ProcessDelegate GetIsWow64ProcessDelegate()
    {
        IntPtr handle = LoadLibrary("kernel32");
    
        if (handle != IntPtr.Zero)
        {
            IntPtr fnPtr = GetProcAddress(handle, "IsWow64Process");
    
            if (fnPtr != IntPtr.Zero)
            {
                return (IsWow64ProcessDelegate)Marshal.GetDelegateForFunctionPointer((IntPtr)fnPtr,
                        typeof(IsWow64ProcessDelegate));
            }
        }
    
        return null;
    }
    
    private static bool Is32BitProcessOn64BitProcessor()
    {
        IsWow64ProcessDelegate fnDelegate = GetIsWow64ProcessDelegate();
    
        if (fnDelegate == null)
        {
            return false;
        }
    
        bool isWow64;
        bool retVal = fnDelegate.Invoke(Process.GetCurrentProcess().Handle, out isWow64);
    
        if (retVal == false)
        {
            return false;
        }
    
        return isWow64;
    }

    If the IntPtr size is 64, then the OS MUST be 64 bits as well because you can't run a 64 bit program on a 32 bit OS.

    If the program is running as 32 bits, then the code checks the process the code runs in to determine if that's 32 or 64 bits.

    If it is 64, then the OS will be 64 bits, but the program is running as 32 bits. And if it's 32 then the OS is also 32 bits.

    In the end, I included most of these methods in the final class lib, because it can be nice to be able to distinguish between the bit architecture of the Program, the OS and the Processor.

Acknowledgements

Thanks to Member 7861383, Scott Vickery for the Windows 8.1 update and workaround.
Thanks to Brisingr Aerowing for help with the Windows 10 adaptation.

History 

  • 2016-02-11 - Version 3.0, Added code for Windows 8.1 & Windows 10
  • 2012-11-21 - Version 2.0, Added version numbers for Windows 8 & Windows Server 2012 
  • 2010-04-15 - Version 1.0, Initial release  

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Sweden Sweden
Born in Copenhagen, Denmark
Have been living in Paris, France and L.A., The United States
Now live in Stockholm, Sweden

Started programming when I got my first VIC 20, and a few months later on Commodore 64. Those were the days!

Studied programming at the Copenhagen Engineering Academy

Professional console, winforms and webforms programming in Comal, x86 Assembler, Fortran, Pascal, Delphi, Visual Basic 3 through 6, Classic ASP, C# and VB.NET

I now work as Senior Microsoft Dynamics AX and .Net programmer, and have a number of projects in various states of progress to work on in the spare time...

Written By
Founder GryphonSoft Technologies
United States United States
I am a student at Ivy Tech Community College in Lafayette, Indiana, majoring in Computer Information Systems. My hobbies are programming computers, playing video games, and sleeping.

My real name is Zachary Greve.

I am also a furry (e.g. a person who likes to believe they are some kind of creature), and my fursona (my creature 'form') is a Gryphon. Sadly, I cannot draw worth a flip.

I like Gryphons.

Comments and Discussions

 
AnswerRe: Windows 10 Pin
Johnny J.11-Aug-15 3:10
professionalJohnny J.11-Aug-15 3:10 
AnswerRe: Windows 10 Pin
TuSung19-Oct-15 17:16
TuSung19-Oct-15 17:16 
QuestionWindows 8.1 and Windows 10 Pin
bprg13-Apr-15 0:18
bprg13-Apr-15 0:18 
AnswerRe: Windows 8.1 and Windows 10 Pin
Johnny J.13-Jul-15 19:39
professionalJohnny J.13-Jul-15 19:39 
QuestionHow? I'm not a programmer. Pin
Member 1095984420-Jul-14 23:21
Member 1095984420-Jul-14 23:21 
AnswerRe: How? I'm not a programmer. Pin
Johnny J.20-Jul-14 23:33
professionalJohnny J.20-Jul-14 23:33 
QuestionPerfect!!! Pin
EvrenY16-May-14 14:36
EvrenY16-May-14 14:36 
AnswerYour Code as VB.NET module Pin
Wallner-Novak29-Apr-14 5:14
professionalWallner-Novak29-Apr-14 5:14 
Thank You for spending time and energy for this class.
As VB-Addict, I translated Your code to VB.
VB
#Region "Imports"
 mports System
Imports System.Collections.Generic
Imports System.Diagnostics
Imports System.Runtime.InteropServices
Imports System.Text
Imports Microsoft.Win32

#End Region

''' <summary>
''' Provides detailed information about the host operating system.
''' Converted to VB.NET from source 
''' http://www.codeproject.com/Articles/73000/Getting-Operating-System-Version-Info-Even-for-Win
''' Copyright by By Johnny J., 21 Nov 2012
''' </summary>
Public Module OSVersionInfo


#Region "ENUMS"
    Public Enum SoftwareArchitecture
        Unknown = 0
        Bit32 = 1
        Bit64 = 2
    End Enum

    Public Enum ProcessorArchitecture
        Unknown = 0
        Bit32 = 1
        Bit64 = 2
        Itanium64 = 3
    End Enum


    ''' <summary>
    ''' Get Bit-String from Enumeration
    ''' </summary>
    ''' <param name="architecture"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function bitString(ByVal architecture As SoftwareArchitecture) As String
        Select Case architecture
            Case SoftwareArchitecture.Bit32
                Return "32bit"
            Case SoftwareArchitecture.Bit64
                Return "64bit"
            Case Else
                Return ""
        End Select
    End Function

    ''' <summary>
    ''' Get Bit-String from Enumeration
    ''' </summary>
    ''' <param name="architecture"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function bitString(ByVal architecture As ProcessorArchitecture) As String
        Select Case architecture
            Case ProcessorArchitecture.Bit32
                Return "x86"
            Case ProcessorArchitecture.Bit64, ProcessorArchitecture.Itanium64
                Return "x64"
            Case Else
                Return ""
        End Select
    End Function
#End Region

#Region "DELEGATE DECLARATION"
    Private Delegate Function IsWow64ProcessDelegate(ByVal handle As IntPtr, ByRef isWow64Process As Boolean) As Boolean
#End Region

#Region "BITS"
    ''' <summary>
    ''' Determines if the current application is 32 or 64-bit.
    ''' </summary>
    Public ReadOnly Property ProgramBits() As SoftwareArchitecture
        Get
            Dim pbits As SoftwareArchitecture = SoftwareArchitecture.Unknown
            Dim test As System.Collections.IDictionary = System.Environment.GetEnvironmentVariables()

            Select Case (IntPtr.Size * 8)
                Case 64
                    pbits = SoftwareArchitecture.Bit64
                Case 32
                    pbits = SoftwareArchitecture.Bit32
                Case Else
                    pbits = SoftwareArchitecture.Unknown
            End Select

            Return pbits
        End Get

    End Property

    ''' <summary>
    ''' 
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property OSBits As SoftwareArchitecture
        Get
            OSBits = SoftwareArchitecture.Unknown

            Select Case (IntPtr.Size * 8)
                Case 64
                    OSBits = SoftwareArchitecture.Bit64

                Case 32
                    If (Is32BitProcessOn64BitProcessor()) Then
                        OSBits = SoftwareArchitecture.Bit64
                    Else
                        OSBits = SoftwareArchitecture.Bit32
                    End If
                Case Else
                    OSBits = SoftwareArchitecture.Unknown
            End Select

            Return OSBits

        End Get
    End Property

    ''' <summary>
    ''' Determines if the current processor is 32 or 64-bit.
    ''' </summary>
    Public ReadOnly Property ProcessorBits As ProcessorArchitecture
        Get
            Dim pbits As ProcessorArchitecture = ProcessorArchitecture.Unknown
            Try

                Dim l_System_Info As SYSTEM_INFO = New SYSTEM_INFO()
                GetNativeSystemInfo(l_System_Info)

                Select Case l_System_Info.uProcessorInfo.wProcessorArchitecture
                    Case 9 ' PROCESSOR_ARCHITECTURE_AMD64
                        pbits = ProcessorArchitecture.Bit64
                    Case 6 ' PROCESSOR_ARCHITECTURE_IA64
                        pbits = ProcessorArchitecture.Itanium64
                    Case 0 ' PROCESSOR_ARCHITECTURE_INTEL
                        pbits = ProcessorArchitecture.Bit32
                    Case Else
                        pbits = ProcessorArchitecture.Unknown
                End Select
            Catch ex As Exception
                'ignore
            End Try

            Return pbits
        End Get
    End Property

#End Region

#Region "EDITION"
     Private s_Edition As String

    ''' <summary>
    ''' Gets the edition of the operating system running on this computer.
    ''' </summary>
    Public ReadOnly Property Edition As String
        Get
            If Not IsNothing(s_Edition) Then
                '***** RETURN *****'
                Return s_Edition
            End If


            Edition = String.Empty

            Dim OSVersion As OperatingSystem = System.Environment.OSVersion
            Dim OSVersionInfo As OSVERSIONINFOEX = New OSVERSIONINFOEX()

            OSVersionInfo.dwOSVersionInfoSize = Marshal.SizeOf(GetType(OSVERSIONINFOEX))

            If (GetVersionEx(OSVersionInfo)) Then
                Dim majorVersion As Integer = OSVersion.Version.Major
                Dim minorVersion As Integer = OSVersion.Version.Minor
                Dim productType As Byte = OSVersionInfo.wProductType
                Dim suiteMask As Short = OSVersionInfo.wSuiteMask

                If majorVersion = 4 Then
                    If productType = VER_NT_WORKSTATION Then
                        ' Windows NT 4.0 Workstation
                        Edition = "Workstation"
                    ElseIf productType = VER_NT_SERVER Then
                        If (suiteMask & VER_SUITE_ENTERPRISE) <> 0 Then
                            ' Windows NT 4.0 Server Enterprise
                            Edition = "Enterprise Server"
                        End If
                    Else
                        ' Windows NT 4.0 Server
                        Edition = "Standard Server"
                    End If

                ElseIf majorVersion = 5 Then
                    If productType = VER_NT_WORKSTATION Then
                        If (suiteMask & VER_SUITE_PERSONAL) <> 0 Then
                            Edition = "Home"
                        Else
                            If GetSystemMetrics(86) = 0 Then
                                ' 86 == SM_TABLETPC
                                Edition = "Professional"
                            Else
                                Edition = "Tablet Edition"
                            End If
                        End If
                    ElseIf productType = VER_NT_SERVER Then
                        If minorVersion = 0 Then
                            If (suiteMask & VER_SUITE_DATACENTER) <> 0 Then
                                ' Windows 2000 Datacenter Server
                                Edition = "Datacenter Server"
                            ElseIf (suiteMask & VER_SUITE_ENTERPRISE) <> 0 Then
                                ' Windows 2000 Advanced Server
                                Edition = "Advanced Server"
                            Else
                                ' Windows 2000 Server
                                Edition = "Server"
                            End If
                        Else
                            If (suiteMask & VER_SUITE_DATACENTER) <> 0 Then
                                ' Windows Server 2003 Datacenter Edition
                                Edition = "Datacenter"
                            ElseIf (suiteMask & VER_SUITE_ENTERPRISE) <> 0 Then
                                ' Windows Server 2003 Enterprise Edition
                                Edition = "Enterprise"
                            ElseIf (suiteMask & VER_SUITE_BLADE) <> 0 Then
                                ' Windows Server 2003 Web Edition
                                Edition = "Web Edition"
                            Else
                                ' Windows Server 2003 Standard Edition
                                Edition = "Standard"
                            End If
                        End If
                    End If
                ElseIf majorVersion = 6 Then
                    Dim ed As Integer
                    If (GetProductInfo(majorVersion, minorVersion, _
                        OSVersionInfo.wServicePackMajor, OSVersionInfo.wServicePackMinor, _
                         ed)) Then
                        Select Case ed
                            Case PRODUCT_BUSINESS
                                Edition = "Business"
                            Case PRODUCT_BUSINESS_N
                                Edition = "Business N"
                            Case PRODUCT_CLUSTER_SERVER
                                Edition = "HPC Edition"
                            Case PRODUCT_CLUSTER_SERVER_V
                                Edition = "HPC Edition without Hyper-V"
                            Case PRODUCT_DATACENTER_SERVER
                                Edition = "Datacenter Server"
                            Case PRODUCT_DATACENTER_SERVER_CORE
                                Edition = "Datacenter Server (core installation)"
                            Case PRODUCT_DATACENTER_SERVER_V
                                Edition = "Datacenter Server without Hyper-V"
                            Case PRODUCT_DATACENTER_SERVER_CORE_V
                                Edition = "Datacenter Server without Hyper-V (core installation)"
                            Case PRODUCT_EMBEDDED
                                Edition = "Embedded"
                            Case PRODUCT_ENTERPRISE
                                Edition = "Enterprise"
                            Case PRODUCT_ENTERPRISE_N
                                Edition = "Enterprise N"
                            Case PRODUCT_ENTERPRISE_E
                                Edition = "Enterprise E"
                            Case PRODUCT_ENTERPRISE_SERVER
                                Edition = "Enterprise Server"
                            Case PRODUCT_ENTERPRISE_SERVER_CORE
                                Edition = "Enterprise Server (core installation)"
                            Case PRODUCT_ENTERPRISE_SERVER_CORE_V
                                Edition = "Enterprise Server without Hyper-V (core installation)"
                            Case PRODUCT_ENTERPRISE_SERVER_IA64
                                Edition = "Enterprise Server for Itanium-based Systems"
                            Case PRODUCT_ENTERPRISE_SERVER_V
                                Edition = "Enterprise Server without Hyper-V"
                            Case PRODUCT_ESSENTIALBUSINESS_SERVER_MGMT
                                Edition = "Essential Business Server MGMT"
                            Case PRODUCT_ESSENTIALBUSINESS_SERVER_ADDL
                                Edition = "Essential Business Server ADDL"
                            Case PRODUCT_ESSENTIALBUSINESS_SERVER_MGMTSVC
                                Edition = "Essential Business Server MGMTSVC"
                            Case PRODUCT_ESSENTIALBUSINESS_SERVER_ADDLSVC
                                Edition = "Essential Business Server ADDLSVC"
                            Case PRODUCT_HOME_BASIC
                                Edition = "Home Basic"
                            Case PRODUCT_HOME_BASIC_N
                                Edition = "Home Basic N"
                            Case PRODUCT_HOME_BASIC_E
                                Edition = "Home Basic E"
                            Case PRODUCT_HOME_PREMIUM
                                Edition = "Home Premium"
                            Case PRODUCT_HOME_PREMIUM_N
                                Edition = "Home Premium N"
                            Case PRODUCT_HOME_PREMIUM_E
                                Edition = "Home Premium E"
                            Case PRODUCT_HOME_PREMIUM_SERVER
                                Edition = "Home Premium Server"
                            Case PRODUCT_HYPERV
                                Edition = "Microsoft Hyper-V Server"
                            Case PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT
                                Edition = "Windows Essential Business Management Server"
                            Case PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING
                                Edition = "Windows Essential Business Messaging Server"
                            Case PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY
                                Edition = "Windows Essential Business Security Server"
                            Case PRODUCT_PROFESSIONAL
                                Edition = "Professional"
                            Case PRODUCT_PROFESSIONAL_N
                                Edition = "Professional N"
                            Case PRODUCT_PROFESSIONAL_E
                                Edition = "Professional E"
                            Case PRODUCT_SB_SOLUTION_SERVER
                                Edition = "SB Solution Server"
                            Case PRODUCT_SB_SOLUTION_SERVER_EM
                                Edition = "SB Solution Server EM"
                            Case PRODUCT_SERVER_FOR_SB_SOLUTIONS
                                Edition = "Server for SB Solutions"
                            Case PRODUCT_SERVER_FOR_SB_SOLUTIONS_EM
                                Edition = "Server for SB Solutions EM"
                            Case PRODUCT_SERVER_FOR_SMALLBUSINESS
                                Edition = "Windows Essential Server Solutions"
                            Case PRODUCT_SERVER_FOR_SMALLBUSINESS_V
                                Edition = "Windows Essential Server Solutions without Hyper-V"
                            Case PRODUCT_SERVER_FOUNDATION
                                Edition = "Server Foundation"
                            Case PRODUCT_SMALLBUSINESS_SERVER
                                Edition = "Windows Small Business Server"
                            Case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM
                                Edition = "Windows Small Business Server Premium"
                            Case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE
                                Edition = "Windows Small Business Server Premium (core installation)"
                            Case PRODUCT_SOLUTION_EMBEDDEDSERVER
                                Edition = "Solution Embedded Server"
                            Case PRODUCT_SOLUTION_EMBEDDEDSERVER_CORE
                                Edition = "Solution Embedded Server (core installation)"
                            Case PRODUCT_STANDARD_SERVER
                                Edition = "Standard Server"
                            Case PRODUCT_STANDARD_SERVER_CORE
                                Edition = "Standard Server (core installation)"
                            Case PRODUCT_STANDARD_SERVER_SOLUTIONS
                                Edition = "Standard Server Solutions"
                            Case PRODUCT_STANDARD_SERVER_SOLUTIONS_CORE
                                Edition = "Standard Server Solutions (core installation)"
                            Case PRODUCT_STANDARD_SERVER_CORE_V
                                Edition = "Standard Server without Hyper-V (core installation)"
                            Case PRODUCT_STANDARD_SERVER_V
                                Edition = "Standard Server without Hyper-V"
                            Case PRODUCT_STARTER
                                Edition = "Starter"
                            Case PRODUCT_STARTER_N
                                Edition = "Starter N"
                            Case PRODUCT_STARTER_E
                                Edition = "Starter E"
                            Case PRODUCT_STORAGE_ENTERPRISE_SERVER
                                Edition = "Enterprise Storage Server"
                            Case PRODUCT_STORAGE_ENTERPRISE_SERVER_CORE
                                Edition = "Enterprise Storage Server (core installation)"
                            Case PRODUCT_STORAGE_EXPRESS_SERVER
                                Edition = "Express Storage Server"
                            Case PRODUCT_STORAGE_EXPRESS_SERVER_CORE
                                Edition = "Express Storage Server (core installation)"
                            Case PRODUCT_STORAGE_STANDARD_SERVER
                                Edition = "Standard Storage Server"
                            Case PRODUCT_STORAGE_STANDARD_SERVER_CORE
                                Edition = "Standard Storage Server (core installation)"
                            Case PRODUCT_STORAGE_WORKGROUP_SERVER
                                Edition = "Workgroup Storage Server"
                            Case PRODUCT_STORAGE_WORKGROUP_SERVER_CORE
                                Edition = "Workgroup Storage Server (core installation)"
                            Case PRODUCT_UNDEFINED
                                Edition = "Unknown product"
                            Case PRODUCT_ULTIMATE
                                Edition = "Ultimate"
                            Case PRODUCT_ULTIMATE_N
                                Edition = "Ultimate N"
                            Case PRODUCT_ULTIMATE_E
                                Edition = "Ultimate E"
                            Case PRODUCT_WEB_SERVER
                                Edition = "Web Server"
                            Case PRODUCT_WEB_SERVER_CORE
                                Edition = "Web Server (core installation)"
                        End Select
                    End If
                End If
            End If

            s_Edition = Edition
            Return Edition

        End Get
    End Property
#End Region

#Region "NAME"
    Private s_Name As String
    ''' <summary>
    ''' Gets the name of the operating system running on this computer.
    ''' </summary>
    Public ReadOnly Property Name As String
        Get

            If Not IsNothing(s_Name) Then
                '***** RETURN *****'
                Return s_Name
            End If

            Name = "unknown"

            Dim OSVersion As OperatingSystem = System.Environment.OSVersion
            Dim OSVersionInfo As OSVERSIONINFOEX = New OSVERSIONINFOEX()

            OSVersionInfo.dwOSVersionInfoSize = Marshal.SizeOf(GetType(OSVERSIONINFOEX))

            If (GetVersionEx(OSVersionInfo)) Then
                Dim majorVersion As Integer = OSVersion.Version.Major
                Dim minorVersion As Integer = OSVersion.Version.Minor

                Select Case OSVersion.Platform
                    Case PlatformID.Win32S
                        Name = "Windows 3.1"
                    Case PlatformID.WinCE
                        Name = "Windows CE"
                    Case PlatformID.Win32Windows
                        If majorVersion = 4 Then
                            Dim csdVersion As String = OSVersionInfo.szCSDVersion
                            Select Case minorVersion
                                Case 0
                                    If (csdVersion = "B" Or csdVersion = "C") Then
                                        Name = "Windows 95 OSR2"
                                    Else
                                        Name = "Windows 95"
                                    End If
                                Case 10
                                    If (csdVersion = "A") Then
                                        Name = "Windows 98 Second Edition"
                                    Else
                                        Name = "Windows 98"
                                    End If
                                Case 90
                                    Name = "Windows Me"
                            End Select
                        End If
                    Case PlatformID.Win32NT
                        Dim productType As Byte = OSVersionInfo.wProductType

                        Select Case (majorVersion)
                            Case 3
                                Name = "Windows NT 3.51"
                            Case 4
                                Select Case productType
                                    Case 1
                                        Name = "Windows NT 4.0"
                                    Case 3
                                        Name = "Windows NT 4.0 Server"
                                End Select
                            Case 5
                                Select Case minorVersion
                                    Case 0
                                        Name = "Windows 2000"
                                    Case 1
                                        Name = "Windows XP"
                                    Case 2
                                        Name = "Windows Server 2003"
                                End Select
                            Case 6
                                ' http://msdn.microsoft.com/en-us/library/windows/desktop/ms724832(v=vs.85).aspx
                                ' For applications that have been manifested for Windows 8.1. Applications not manifested for 8.1 will return the Windows 8 OS version value (6.2). 
                                ' By reading the registry, we'll get the exact version - meaning we can even compare against  Win 8 and Win 8.1.
                                Dim exactVersion As String = Registry.GetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentVersion", "")
                                If Not (String.IsNullOrWhiteSpace(exactVersion)) Then
                                    Dim split_result As String() = exactVersion.Split(".")
                                    majorVersion = Convert.ToInt32(split_result(0))
                                    minorVersion = Convert.ToInt32(split_result(1))
                                End If

                                Select Case minorVersion
                                    Case 0
                                        Select Case productType
                                            Case 1
                                                Name = "Windows Vista"
                                            Case 3
                                                Name = "Windows Server 2008"
                                        End Select
                                    Case 1
                                        Select Case productType
                                            Case 1
                                                Name = "Windows 7"
                                            Case 3
                                                Name = "Windows Server 2008 R2"
                                        End Select
                                    Case 2
                                        Select Case productType
                                            Case 1
                                                Name = "Windows 8"
                                            Case 3
                                                Name = "Windows Server 2012"
                                        End Select
                                    Case 3
                                        Select Case productType
                                            Case 1
                                                Name = "Windows 8.1"
                                            Case 3
                                                Name = "Windows Server 2012"
                                        End Select
                                End Select
                        End Select
                End Select
            End If

            s_Name = Name
            Return Name
        End Get
    End Property
#End Region

#Region "GET PRODUCT INFO"
    <DllImport("Kernel32.dll")>
    Private Function GetProductInfo( _
             ByVal osMajorVersion As Integer, _
            ByVal osMinorVersion As Integer, _
            ByVal spMajorVersion As Integer, _
            ByVal spMinorVersion As Integer, _
            ByRef edition As Integer) As Boolean
    End Function
#End Region

#Region "VERSION"
    <DllImport("kernel32")> _
    Private Function GetVersionEx(ByRef osvi As OSVERSIONINFOEX) As Boolean
    End Function
#End Region

#Region "SYSTEMMETRICS"
    <DllImport("user32")>
    Public Function GetSystemMetrics(ByVal nIndex As Integer) As Integer
    End Function
#End Region

#Region "SYSTEMINFO"
    <DllImport("kernel32.dll")> _
    Public Sub GetSystemInfo(<MarshalAs(UnmanagedType.Struct)> ByRef lpSystemInfo As SYSTEM_INFO)
    End Sub

    <DllImport("kernel32.dll")>
    Private Sub GetNativeSystemInfo(<MarshalAs(UnmanagedType.Struct)> ByRef lpSystemInfo As SYSTEM_INFO)
    End Sub
#End Region


#Region "OSVERSIONINFOEX"
    <StructLayout(LayoutKind.Sequential)>
    Private Structure OSVERSIONINFOEX
        Public dwOSVersionInfoSize As Integer
        Public dwMajorVersion As Integer
        Public dwMinorVersion As Integer
        Public dwBuildNumber As Integer
        Public dwPlatformId As Integer
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=128)>
        Public szCSDVersion As String
        Public wServicePackMajor As Short
        Public wServicePackMinor As Short
        Public wSuiteMask As Short
        Public wProductType As Byte
        Public wReserved As Byte
    End Structure
#End Region

#Region "SYSTEM_INFO"
    <StructLayout(LayoutKind.Sequential)>
    Public Structure SYSTEM_INFO
        Public uProcessorInfo As _PROCESSOR_INFO_UNION
        Public dwPageSize As UInteger
        Public lpMinimumApplicationAddress As IntPtr
        Public lpMaximumApplicationAddress As IntPtr
        Public dwActiveProcessorMask As IntPtr
        Public dwNumberOfProcessors As UInteger
        Public dwProcessorType As UInteger
        Public dwAllocationGranularity As UInteger
        Public dwProcessorLevel As UShort
        Public dwProcessorRevision As UShort
    End Structure
#End Region

#Region "_PROCESSOR_INFO_UNION"
    <StructLayout(LayoutKind.Explicit)>
    Public Structure _PROCESSOR_INFO_UNION
        <FieldOffset(0)>
        Public dwOemId As UInteger
        <FieldOffset(0)>
        Public wProcessorArchitecture As UShort
        <FieldOffset(2)>
        Public wReserved As UShort
    End Structure
#End Region

#Region "64 BIT OS DETECTION"
    <DllImport("kernel32.dll", SetLastError:=True, CallingConvention:=CallingConvention.Winapi)> _
    Public Function LoadLibraryA(ByVal lpFileName As String) As IntPtr
    End Function

    <DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Ansi, ExactSpelling:=True, CallingConvention:=CallingConvention.Winapi)> _
    Private Function GetProcAddress(ByVal hModule As IntPtr, ByVal procName As String) As IntPtr
    End Function
#End Region

#Region "PRODUCT"
    Private Const PRODUCT_UNDEFINED As Integer = &H0
    Private Const PRODUCT_ULTIMATE As Integer = &H1
    Private Const PRODUCT_HOME_BASIC As Integer = &H2
    Private Const PRODUCT_HOME_PREMIUM As Integer = &H3
    Private Const PRODUCT_ENTERPRISE As Integer = &H4
    Private Const PRODUCT_HOME_BASIC_N As Integer = &H5
    Private Const PRODUCT_BUSINESS As Integer = &H6
    Private Const PRODUCT_STANDARD_SERVER As Integer = &H7
    Private Const PRODUCT_DATACENTER_SERVER As Integer = &H8
    Private Const PRODUCT_SMALLBUSINESS_SERVER As Integer = &H9
    Private Const PRODUCT_ENTERPRISE_SERVER As Integer = &HA
    Private Const PRODUCT_STARTER As Integer = &HB
    Private Const PRODUCT_DATACENTER_SERVER_CORE As Integer = &HC
    Private Const PRODUCT_STANDARD_SERVER_CORE As Integer = &HD
    Private Const PRODUCT_ENTERPRISE_SERVER_CORE As Integer = &HE
    Private Const PRODUCT_ENTERPRISE_SERVER_IA64 As Integer = &HF
    Private Const PRODUCT_BUSINESS_N As Integer = &H10
    Private Const PRODUCT_WEB_SERVER As Integer = &H11
    Private Const PRODUCT_CLUSTER_SERVER As Integer = &H12
    Private Const PRODUCT_HOME_SERVER As Integer = &H13
    Private Const PRODUCT_STORAGE_EXPRESS_SERVER As Integer = &H14
    Private Const PRODUCT_STORAGE_STANDARD_SERVER As Integer = &H15
    Private Const PRODUCT_STORAGE_WORKGROUP_SERVER As Integer = &H16
    Private Const PRODUCT_STORAGE_ENTERPRISE_SERVER As Integer = &H17
    Private Const PRODUCT_SERVER_FOR_SMALLBUSINESS As Integer = &H18
    Private Const PRODUCT_SMALLBUSINESS_SERVER_PREMIUM As Integer = &H19
    Private Const PRODUCT_HOME_PREMIUM_N As Integer = &H1A
    Private Const PRODUCT_ENTERPRISE_N As Integer = &H1B
    Private Const PRODUCT_ULTIMATE_N As Integer = &H1C
    Private Const PRODUCT_WEB_SERVER_CORE As Integer = &H1D
    Private Const PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT As Integer = &H1E
    Private Const PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY As Integer = &H1F
    Private Const PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING As Integer = &H20
    Private Const PRODUCT_SERVER_FOUNDATION As Integer = &H21
    Private Const PRODUCT_HOME_PREMIUM_SERVER As Integer = &H22
    Private Const PRODUCT_SERVER_FOR_SMALLBUSINESS_V As Integer = &H23
    Private Const PRODUCT_STANDARD_SERVER_V As Integer = &H24
    Private Const PRODUCT_DATACENTER_SERVER_V As Integer = &H25
    Private Const PRODUCT_ENTERPRISE_SERVER_V As Integer = &H26
    Private Const PRODUCT_DATACENTER_SERVER_CORE_V As Integer = &H27
    Private Const PRODUCT_STANDARD_SERVER_CORE_V As Integer = &H28
    Private Const PRODUCT_ENTERPRISE_SERVER_CORE_V As Integer = &H29
    Private Const PRODUCT_HYPERV As Integer = &H2A
    Private Const PRODUCT_STORAGE_EXPRESS_SERVER_CORE As Integer = &H2B
    Private Const PRODUCT_STORAGE_STANDARD_SERVER_CORE As Integer = &H2C
    Private Const PRODUCT_STORAGE_WORKGROUP_SERVER_CORE As Integer = &H2D
    Private Const PRODUCT_STORAGE_ENTERPRISE_SERVER_CORE As Integer = &H2E
    Private Const PRODUCT_STARTER_N As Integer = &H2F
    Private Const PRODUCT_PROFESSIONAL As Integer = &H30
    Private Const PRODUCT_PROFESSIONAL_N As Integer = &H31
    Private Const PRODUCT_SB_SOLUTION_SERVER As Integer = &H32
    Private Const PRODUCT_SERVER_FOR_SB_SOLUTIONS As Integer = &H33
    Private Const PRODUCT_STANDARD_SERVER_SOLUTIONS As Integer = &H34
    Private Const PRODUCT_STANDARD_SERVER_SOLUTIONS_CORE As Integer = &H35
    Private Const PRODUCT_SB_SOLUTION_SERVER_EM As Integer = &H36
    Private Const PRODUCT_SERVER_FOR_SB_SOLUTIONS_EM As Integer = &H37
    Private Const PRODUCT_SOLUTION_EMBEDDEDSERVER As Integer = &H38
    Private Const PRODUCT_SOLUTION_EMBEDDEDSERVER_CORE As Integer = &H39
    'private const ???? as integer = &H0000003A
    Private Const PRODUCT_ESSENTIALBUSINESS_SERVER_MGMT As Integer = &H3B
    Private Const PRODUCT_ESSENTIALBUSINESS_SERVER_ADDL As Integer = &H3C
    Private Const PRODUCT_ESSENTIALBUSINESS_SERVER_MGMTSVC As Integer = &H3D
    Private Const PRODUCT_ESSENTIALBUSINESS_SERVER_ADDLSVC As Integer = &H3E
    Private Const PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE As Integer = &H3F
    Private Const PRODUCT_CLUSTER_SERVER_V As Integer = &H40
    Private Const PRODUCT_EMBEDDED As Integer = &H41
    Private Const PRODUCT_STARTER_E As Integer = &H42
    Private Const PRODUCT_HOME_BASIC_E As Integer = &H43
    Private Const PRODUCT_HOME_PREMIUM_E As Integer = &H44
    Private Const PRODUCT_PROFESSIONAL_E As Integer = &H45
    Private Const PRODUCT_ENTERPRISE_E As Integer = &H46
    Private Const PRODUCT_ULTIMATE_E As Integer = &H47
    'private const PRODUCT_UNLICENSED as integer = &HABCDABCD
#End Region

#Region "VERSIONS"
    Private Const VER_NT_WORKSTATION As Integer = 1
    Private Const VER_NT_DOMAIN_CONTROLLER As Integer = 2
    Private Const VER_NT_SERVER As Integer = 3
    Private Const VER_SUITE_SMALLBUSINESS As Integer = 1
    Private Const VER_SUITE_ENTERPRISE As Integer = 2
    Private Const VER_SUITE_TERMINAL As Integer = 16
    Private Const VER_SUITE_DATACENTER As Integer = 128
    Private Const VER_SUITE_SINGLEUSERTS As Integer = 256
    Private Const VER_SUITE_PERSONAL As Integer = 512
    Private Const VER_SUITE_BLADE As Integer = 1024
#End Region

#Region "SERVICE PACK"
    ''' <summary>
    ''' Gets the service pack information of the operating system running on this computer.
    ''' </summary>
    Public ReadOnly Property ServicePack() As String
        Get

            ServicePack = String.Empty
            Dim osVersionInfo As OSVERSIONINFOEX = New OSVERSIONINFOEX()

            osVersionInfo.dwOSVersionInfoSize = Marshal.SizeOf(GetType(OSVERSIONINFOEX))

            If GetVersionEx(osVersionInfo) Then
                ServicePack = osVersionInfo.szCSDVersion
            End If

            Return ServicePack
        End Get
    End Property
#End Region

#Region "VERSION"
    ''' <summary>
    ''' Gets the build version number of the operating system running on this computer.
    ''' </summary>
    Public ReadOnly Property BuildVersion() As Integer
        Get
            Return System.Environment.OSVersion.Version.Build
        End Get
    End Property

    ''' <summary>
    ''' Gets the full version string of the operating system running on this computer.
    ''' </summary>
    Public ReadOnly Property VersionString As String
        Get
            Return System.Environment.OSVersion.Version.ToString()
        End Get
    End Property

    ''' <summary>
    ''' Gets the full version of the operating system running on this computer.
    ''' </summary>
    Public ReadOnly Property Version As Version
        Get
            Return System.Environment.OSVersion.Version
        End Get
    End Property

    ''' <summary>
    ''' Gets the major version number of the operating system running on this computer.
    ''' </summary>
    Public ReadOnly Property MajorVersion As Integer
        Get
            Return System.Environment.OSVersion.Version.Major
        End Get
    End Property

    ''' <summary>
    ''' Gets the minor version number of the operating system running on this computer.
    ''' </summary>
    Public ReadOnly Property MinorVersion As Integer
        Get
            Return System.Environment.OSVersion.Version.Minor
        End Get
    End Property

    ''' <summary>
    ''' Gets the revision version number of the operating system running on this computer.
    ''' </summary>
    Public ReadOnly Property RevisionVersion As Integer
        Get
            Return System.Environment.OSVersion.Version.Revision
        End Get
    End Property
#End Region

#Region "64 BIT OS DETECTION"
    Private Function GetIsWow64ProcessDelegate() As IsWow64ProcessDelegate

        Dim handle As IntPtr = LoadLibraryA("kernel32")

        If handle <> IntPtr.Zero Then

            Dim fnPtr As IntPtr = GetProcAddress(handle, "IsWow64Process")

            If fnPtr <> IntPtr.Zero Then
                Return Marshal.GetDelegateForFunctionPointer(fnPtr, GetType(IsWow64ProcessDelegate))
            End If

            Return Nothing
        End If

        Return Nothing
    End Function

    Private Function Is32BitProcessOn64BitProcessor() As Boolean

        Dim fnDelegate As IsWow64ProcessDelegate = GetIsWow64ProcessDelegate()

        If IsNothing(fnDelegate) Then Return False

        Dim isWow64 As Boolean

        Dim retVal As Boolean = fnDelegate.Invoke(Process.GetCurrentProcess().Handle, isWow64)

        If retVal = False Then Return False

        Return isWow64
    End Function

#End Region

End Module

General...and now updated for Windows 8.1 ! Pin
ShR33k20-Oct-13 7:56
ShR33k20-Oct-13 7:56 
GeneralRe: ...and now updated for Windows 8.1 ! Pin
Johnny J.11-Aug-15 3:17
professionalJohnny J.11-Aug-15 3:17 
QuestionWindows Home Server Pin
Havoxx7-Aug-13 0:14
Havoxx7-Aug-13 0:14 
AnswerRe: Windows Home Server Pin
Johnny J.10-Aug-13 14:52
professionalJohnny J.10-Aug-13 14:52 
QuestionServer 2012 issue. Pin
rasmuffin129-May-13 7:34
rasmuffin129-May-13 7:34 
BugWindows Server 2003 R2 x64 Error Pin
Member 855836922-Mar-13 2:33
Member 855836922-Mar-13 2:33 
NewsImportant: All is useless in Compatibility Mode Pin
Elmue14-Jan-13 16:57
Elmue14-Jan-13 16:57 
GeneralRe: Important: All is useless in Compatibility Mode Pin
ledtech324-Aug-13 10:48
ledtech324-Aug-13 10:48 
QuestionPerfect Pin
nishantenet21-Nov-12 8:00
nishantenet21-Nov-12 8:00 
AnswerRe: Perfect Pin
Johnny J.21-Nov-12 19:55
professionalJohnny J.21-Nov-12 19:55 
QuestionArticle updated! Pin
Johnny J.20-Nov-12 22:47
professionalJohnny J.20-Nov-12 22:47 
AnswerRe: Article updated! Pin
dherrmann20-Nov-12 23:07
dherrmann20-Nov-12 23:07 
GeneralRe: Article updated! Pin
Johnny J.20-Nov-12 23:09
professionalJohnny J.20-Nov-12 23:09 
AnswerRe: Article updated! Pin
Akinmade Bond25-Apr-13 6:35
professionalAkinmade Bond25-Apr-13 6:35 
QuestionWindows 8 is on the road!!! Pin
dherrmann16-Nov-12 6:41
dherrmann16-Nov-12 6:41 
AnswerRe: Windows 8 is on the road!!! Pin
Johnny J.20-Nov-12 22:45
professionalJohnny J.20-Nov-12 22:45 
QuestionDetect Server Pin
Derek Hart5-Oct-12 10:13
Derek Hart5-Oct-12 10:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.