Visual Basic Helper Routines
GetVersionEx: Windows Version Info (Wrapper Routines)
     
Posted:   Saturday August 14, 1999
Updated:   Monday December 26, 2011
     
Applies to:   VB4-32, VB5, VB6
Developed with:   VB6, Windows NT4, Windows 2000, Windows XP, Windows Vista
OS restrictions:   None
Author:   VBnet - Randy Birch
     

Related:  

GetVersionEx: Windows Version, Service Pack and Platform Info
GetFileVersionInfo: Handy Routines for Identifying Shell32 Versions
GetSystemInfo: System Processor Information

NetServerGetInfo: Configuration Info for Domain/Workgroup Servers and Machines
     
 Prerequisites
None.

This page provides a series of wrapper routines that can be called from anywhere in your app. Each simply returns True when the matching operation system version or feature is found. Once you've examined the code below you will see how easily you can create your own derivations by modifying the appropriate values.

Notice that the illustration shows multiple True values. In addition to testing for specific operating systems or features, the wrappers below also provide tests for 'minimum' OS versions. Thus if you have a routine that only runs under NT4 or later, you can wrap that call in the IsWinNT4Plus() return value. If the system is NT4, Win 2000, XP home or Pro editions, Windows Vista, or Windows Server 2003 or 2008, the value will be True.

The OSVERSIONINFO structure has evolved through Windows versions to create a second, larger structure: OSVERSIONINFOEX. The 'EX' flavour adds five new UDT members providing additional system information such as the service pack version, suite (windows type), and product type. While all versions of Windows can use the OSVERSIONINFO structure, the EX version is only supported under NT4 workstation SP6, and Windows 2000, XP, 2003 (.NET server), and Vista. To provide the additional data, the 'EX' structure is 8 bytes larger than the older structure.

This poses a problem for the developer writing apps targeting both newer and legacy Windows versions who want to reuse routines as much as possible yet require the ability, under NT-based boxes, to query for additional information. Two solutions are available. The one shown here is the easiest to implement: each wrapper uses either the smallest required structure needed to obtain the data requested . Where the call is being made just to determine the OS version, the wrapper routine uses the OSVERSIONINFO structure as only parameters common to both this and the OSVERSIONINFOEX structure are required to successfully determine the OS version. When testing for features specific to systems requiring a minimum OS version, a call is first made to the low-grade wrapper to ensure the system supports the OSVERSIONINFOEX structure, which is subsequently used to determine the specific information extracted from the additional data this -EX structure provides.  Each routine's local OSV is hard-coded to use the appropriate structure, facilitating referencing Len(osv) to set the required OSVSize parameter of the structure. To provide support for both structure sizes, this requires the GetVersionInfoEx API's lpVersionInformation parameter to be defined As Any.

The alternative method (to be added to the site later) will contain a wrapper, called on load, which performs a series of progressive tests to identify the windows version, starting with Win95, then sets a constant equal to the supported OSV length. That value is used in all subsequent calls, with tests to ensure a Win9x test is not made on a WinNT box. Since setting the value essentially 'clips' the OSVERSIONINFOEX structure to simulate the OSVERSIONINFO structure needed under 9x, only one UDT is required and the value passed to GetVersionEx can be declared As OSVERSIONINFOEX. Which you ultimately choose to implement will be based on your determined needs.

To summarize, the base version info returned by GetVersionEx for various Windows versions is:


  Win 95 Win 95 OSR2 Win 98 Win SE Win Me Win NT 4 Win 2000 Win XP Win XP SP2 Win 2003 Server Win Vista Win Vista SP1
PlatformID 1 1 1 1 1 2 2 2 2
2
2
2
Major Version 4 4 4 4 4 4 5 5 5
5
6
6
Minor Version 0 0 10 10 90 0 0 1 1
2
0
0
Build 950* 1111 1998 2222 3000 1381 2195 2600 2600
3790
6000
6001

Finally, note that MS recommends GetVersionEx be used appropriately. While it is perfectly safe to call GetVersion or GetVersionEx as often as needed, MS points out that identifying the current operating system is usually not the best way to determine whether a particular operating system *feature* is present, because the OS may have had new features added through a service pack or in a redistributable DLL. Their recommendation on Window versions prior to Vista is to test for the presence of the feature itself, rather than using GetVersionEx to determine the operating system platform or version number.  For Vista (actually version 6 operating systems), a new API was introduced to retrieve what MS call Product Info - the ability to determine specific version 6 Windows versions. For Vista, this means identifying systems running Home, Home Premium, Business, Ultimate etc. Windows 2008 Server also supports GetProductInfo.

 

Revision History

April 15.2008     Added IsWindowsVistaHome, IsWindowsVistaHomePremium,  IsWindowsVistaBusiness, IsWindowsVistaEnterprise, IsWindowsVistaUltimate, IsWindowsVistaHomeServer.  
Sept 20.2006     Thanks to Ed Bihary for a couple of corrections to the version table build numbers.
Sept 8.2006     Added IsWinLonghorn, IsWinXPMediaCenter, IsWinXPStarter, IsWinXPTabletPc, IsWinXPEmbedded, IsWinXP64, IsWin2003ServerR2, IsWinVista and IsWinVistaPlus. The items in bold still need to be verified. If you find the code works (or doesn't) please fire me an email via the Comments button at the left.
Aug 21.2004  Added IsWinXPSP2 test
Mar 18.2004     Thanks to Bron Davies for fixes to correctly return IsWin2000AdvancedServer and IsDomainController.
Nov 11.2003     Thanks go out to Patrick Martineau for providing the build number for Windows 2003 Server (.NET Server).

 BAS Module Code
None, though in due to the versatility of this code it would be prudent to develop a specific "WinVersion" BAS or CLS file to hold this set of routines.

 Form Code
On a form, add a command button, a textbox (Text1) and a label (Label1). Set the Index property of both the text box and label to 0 to establish each as a control array. The load event takes care of creating and positioning the required controls and resizing the form (as coded the positioning works for for a small-font system; some adjustment may be needed for non-standard display attributes).

Add the following code to the form:


Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce 
'               or publish this code on any web site,
'               online service, or distribute as source 
'               on any media without express permission.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'dwPlatformId
Private Const VER_PLATFORM_WIN32s As Long = 0
Private Const VER_PLATFORM_WIN32_WINDOWS As Long = 1
Private Const VER_PLATFORM_WIN32_NT As Long = 2

'os product type values
Private Const VER_NT_WORKSTATION As Long = &H1
Private Const VER_NT_DOMAIN_CONTROLLER As Long = &H2
Private Const VER_NT_SERVER As Long = &H3

'product types
Private Const VER_SERVER_NT As Long = &H80000000
Private Const VER_WORKSTATION_NT As Long = &H40000000

Private Const VER_SUITE_SMALLBUSINESS As Long = &H1
Private Const VER_SUITE_ENTERPRISE As Long = &H2
Private Const VER_SUITE_BACKOFFICE As Long = &H4
Private Const VER_SUITE_COMMUNICATIONS As Long = &H8
Private Const VER_SUITE_TERMINAL As Long = &H10
Private Const VER_SUITE_SMALLBUSINESS_RESTRICTED As Long = &H20
Private Const VER_SUITE_EMBEDDEDNT = &H40
Private Const VER_SUITE_DATACENTER As Long = &H80
Private Const VER_SUITE_SINGLEUSERTS As Long = &H100
Private Const VER_SUITE_PERSONAL As Long = &H200
Private Const VER_SUITE_BLADE As Long = &H400

Private Const OSV_LENGTH As Long = 148
Private Const OSVEX_LENGTH As Long = 156


Private Const SM_TABLETPC As Long = 86
Private Const SM_MEDIACENTER As Long = 87
Private Const SM_STARTER As Long = 88
Private Const SM_SERVERR2 As Long = 89

Private Const PROCESSOR_ARCHITECTURE_IA64 As Long = 6


Private Type OSVERSIONINFO
  OSVSize         As Long         'size, in bytes, of this data structure
  dwVerMajor      As Long         'ie NT 3.51, dwVerMajor = 3; NT 4.0, dwVerMajor = 4.
  dwVerMinor      As Long         'ie NT 3.51, dwVerMinor = 51; NT 4.0, dwVerMinor= 0.  
  dwBuildNumber   As Long         'NT: build number of the OS
                                  'Win9x: build number of the OS in low-order word.
                                  '       High-order word contains major & minor ver nos.
  PlatformID      As Long         'Identifies the operating system platform.
  szCSDVersion    As String * 128 'NT: string, such as "Service Pack 3"
                                  'Win9x: string providing arbitrary additional information
End Type

Private Type OSVERSIONINFOEX
  OSVSize            As Long
  dwVerMajor        As Long
  dwVerMinor         As Long
  dwBuildNumber      As Long
  PlatformID         As Long
  szCSDVersion       As String * 128
  wServicePackMajor  As Integer
  wServicePackMinor  As Integer
  wSuiteMask         As Integer
  wProductType       As Byte
  wReserved          As Byte
End Type

Private Type SYSTEM_INFO
   dwOemID As Long
   dwPageSize As Long
   lpMinimumApplicationAddress As Long
   lpMaximumApplicationAddress As Long
   dwActiveProcessorMask As Long
   dwNumberOfProcessors As Long
   dwProcessorType As Long
   dwAllocationGranularity As Long
   wProcessorLevel As Integer
   wProcessorRevision As Integer
End Type

'defined As Any to support OSVERSIONINFO and OSVERSIONINFOEX
Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" _
  (lpVersionInformation As Any) As Long
  
Private Declare Function GetSystemMetrics Lib "user32" _
  (ByVal nIndex As Long) As Long  

Private Declare Sub GetSystemInfo Lib "kernel32" _
   (lpSystemInfo As SYSTEM_INFO)
   
   
Private Declare Function GetProductInfo Lib "kernel32" _
  (ByVal dwOSMajorVersion As Long, _
   ByVal dwOSMinorVersion As Long, _
   ByVal dwSpMajorVersion As Long, _
   ByVal dwSpMinorVersion As Long, _
   pdwReturnedProductType As Long) As Long

'GetProductInfo possible values
Private Const PRODUCT_UNDEFINED = &H0  'An unknown product
Private Const PRODUCT_ULTIMATE = &H1  'Ultimate Edition
Private Const PRODUCT_HOME_BASIC = &H2  'Home Basic Edition
Private Const PRODUCT_HOME_PREMIUM = &H3  'Home Premium Edition
Private Const PRODUCT_ENTERPRISE = &H4  'Enterprise Edition
Private Const PRODUCT_HOME_BASIC_N = &H5  'Home Basic Edition
Private Const PRODUCT_BUSINESS = &H6  'Business Edition
Private Const PRODUCT_STANDARD_SERVER = &H7  'Server Standard Edition (full installation)
Private Const PRODUCT_DATACENTER_SERVER = &H8  'Server Datacenter Edition (full installation)
Private Const PRODUCT_SMALLBUSINESS_SERVER = &H9  'Small Business Server
Private Const PRODUCT_ENTERPRISE_SERVER = &HA  'Server Enterprise Edition (full installation)
Private Const PRODUCT_STARTER = &HB  'Starter Edition
Private Const PRODUCT_DATACENTER_SERVER_CORE = &HC  'Server Datacenter Edition (core installation)
Private Const PRODUCT_STANDARD_SERVER_CORE = &HD  'Server Standard Edition (core installation)
Private Const PRODUCT_ENTERPRISE_SERVER_CORE = &HE  'Server Enterprise Edition (core installation)
Private Const PRODUCT_ENTERPRISE_SERVER_IA64 = &HF  'Server Enterprise Edition for Itanium-based Systems
Private Const PRODUCT_BUSINESS_N = &H10  'Business Edition
Private Const PRODUCT_WEB_SERVER = &H11  'Web Server Edition (full installation)
Private Const PRODUCT_CLUSTER_SERVER = &H12  'Cluster Server Edition
Private Const PRODUCT_HOME_SERVER = &H13  'Home Server Edition
Private Const PRODUCT_STORAGE_EXPRESS_SERVER = &H14  'Storage Server Express Edition
Private Const PRODUCT_STORAGE_STANDARD_SERVER = &H15  'Storage Server Standard Edition
Private Const PRODUCT_STORAGE_WORKGROUP_SERVER = &H16  'Storage Server Workgroup Edition
Private Const PRODUCT_STORAGE_ENTERPRISE_SERVER = &H17  'Storage Server Enterprise Edition
Private Const PRODUCT_SERVER_FOR_SMALLBUSINESS = &H18  'Server for Small Business Edition
Private Const PRODUCT_SMALLBUSINESS_SERVER_PREMIUM = &H19  'Small Business Server Premium Edition
Private Const PRODUCT_HOME_PREMIUM_N = &H1A  'Home Premium Edition
Private Const PRODUCT_ENTERPRISE_N = &H1B  'Enterprise Edition
Private Const PRODUCT_ULTIMATE_N = &H1C  'Ultimate Edition
Private Const PRODUCT_WEB_SERVER_CORE = &H1D  'Web Server Edition (core installation)
Private Const PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT = &H1E  'Windows Essential Business Server Management Server
Private Const PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY = &H1F  'Windows Essential Business Server Security Server
Private Const PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING = &H20  'Windows Essential Business Server Messaging Server
Private Const PRODUCT_STANDARD_SERVER_V = &H24  'Server Standard Edition without Hyper-V (full installation)
Private Const PRODUCT_DATACENTER_SERVER_V = &H25  'Server Datacenter Edition without Hyper-V (full installation)
Private Const PRODUCT_ENTERPRISE_SERVER_V = &H26  'Server Enterprise Edition without Hyper-V (full installation)
Private Const PRODUCT_DATACENTER_SERVER_CORE_V = &H27  'Server Datacenter Edition without Hyper-V (core installation)
Private Const PRODUCT_STANDARD_SERVER_CORE_V = &H28  'Server Standard Edition without Hyper-V (core installation)
Private Const PRODUCT_ENTERPRISE_SERVER_CORE_V = &H29  'Server Enterprise Edition without Hyper-V (core installation)
   
   
   

Private Sub Form_Load()

   Dim cnt As Long
   Dim nControls As Long
   Dim nRows As Long
   Dim nCols As Long
   Dim nMaxCtrlsPerCol As Long
   Dim hOffset As Single
   Dim vOffset As Single
   
   nControls = 42  '0-based
   nRows = 2
   nCols = 2
   nMaxCtrlsPerCol = nControls \ 2
   
   For cnt = 0 To nControls - 1
   
     'control(0) already exists; don't try to load it!
      If cnt > 0 Then
         Load Label1(cnt)
         Load Text1(cnt)
      End If
      
    'position and show
     If cnt < nMaxCtrlsPerCol Then
         hOffset = 1
         vOffset = cnt
     Else
        hOffset = 2.4
        vOffset = (cnt - nMaxCtrlsPerCol)
     End If
         
      With Text1(cnt)
         .Move (3300 * hOffset), 200 + (vOffset * 300), 1300, 285
         .Text = ""
         .Visible = True
      End With
      
      With Label1(cnt)
         .Alignment = vbRightJustify
         .AutoSize = True
         .Move Text1(cnt).Left - 200, (230 + (vOffset * 300)), 0, 195
         .Visible = True
      End With
              
   Next
   
   With Command1
       .Move Text1(0).Left, _
             Text1(nControls - 1).Top + _
             Text1(nControls - 1).Height + 230, _
             Text1(0).Width
                 
   		.TabIndex = 0
   		.Caption = "What Version?"
   End With
   
   Me.Move Me.Left, Me.Top, _
          (Text1(nControls - 1).Left + Text1(nControls - 1).Width + 1000), _
          (Command1.Top + Command1.Height + 800)

End Sub


Private Sub Command1_Click()

   Dim cnt As Long

   Label1(0).Caption = "Is Windows 95 ?"
   Label1(1).Caption = "Is Windows 95 OSR2 ?"
   Label1(2).Caption = "Is Windows 98 ?"
   Label1(3).Caption = "Is Windows ME ?"
   
   Label1(4).Caption = "Is Windows NT4 ?"
   Label1(5).Caption = "Is Windows NT4 Plus ?"
   Label1(6).Caption = "Is Windows NT4 Server ?"
   Label1(7).Caption = "Is Windows NT4 Workstation ?"
   
   Label1(8).Caption = "Is Windows 2000 ?"
   Label1(9).Caption = "Is Windows 2000 Plus ?"
   Label1(10).Caption = "Is Windows 2000 Server ?"
   Label1(11).Caption = "Is Windows 2000 Advanced Server ?"
   Label1(12).Caption = "Is Windows 2000 Workstation ?"
   
   Label1(13).Caption = "Is Windows XP ?"
   Label1(14).Caption = "Is Windows XP Plus ?"
   Label1(15).Caption = "Is Windows XP Home ?"
   Label1(16).Caption = "Is Windows XP Pro ?"
   Label1(17).Caption = "Is Windows XP Service Pack 2 ?"
   
   Label1(18).Caption = "Is Windows XP Media Center Edition ?"
   Label1(19).Caption = "Is Windows XP Starter Edition ?"
   Label1(20).Caption = "Is Windows XP Tablet PC Edition ?"
   Label1(21).Caption = "Is Windows XP Embedded ?"
   
   Label1(22).Caption = "Is Windows XP 64-bit ?"
   
   Label1(23).Caption = "Is Windows Vista ?"
   Label1(24).Caption = "Is Windows Vista Plus ?"
   
   Label1(25).Caption = "Is Windows Vista Home Basic ?"
   Label1(26).Caption = "Is Windows Vista Home Premium ?"
   Label1(27).Caption = "Is Windows Vista Business ?"
   Label1(28).Caption = "Is Windows Vista Enterprise ?"
   Label1(29).Caption = "Is Windows Vista Ultimate ?"
   Label1(30).Caption = "Is Windows Vista Home Server ?"
   Label1(31).Caption = "Is Windows Vista Service Pack 1 ?"
   
   Label1(32).Caption = "Is Windows 2003 Server ?"
   Label1(33).Caption = "Is Windows 2003 Server RC2 ?"
   
   Label1(34).Caption = "Is Windows Longhorn Server ?"
   
   Label1(35).Caption = "Is BackOffice Server ?"
   Label1(36).Caption = "Is Blade Server ?"
   Label1(37).Caption = "Is Domain Controller ?"
   Label1(38).Caption = "Is Enterprise Server ?"
   Label1(39).Caption = "Is Small Business Server ?"
   Label1(40).Caption = "Is Small Business Restricted Server ?"
   Label1(41).Caption = "Is Terminal Server ?"
   
   Text1(0).Text = IsWin95()
   Text1(1).Text = IsWin95OSR2()
   Text1(2).Text = IsWin98()
   Text1(3).Text = IsWinME()
   
   Text1(4).Text = IsWinNT4()
   Text1(5).Text = IsWinNT4Plus()
   Text1(6).Text = IsWinNT4Server()
   Text1(7).Text = IsWinNT4Workstation()
   
   Text1(8).Text = IsWin2000()
   Text1(9).Text = IsWin2000Plus()
   Text1(10).Text = IsWin2000Server()
   Text1(11).Text = IsWin2000AdvancedServer
   Text1(12).Text = IsWin2000Workstation()
      
   Text1(13).Text = IsWinXP()
   Text1(14).Text = IsWinXPPlus()
   Text1(15).Text = IsWinXPHomeEdition()
   Text1(16).Text = IsWinXPProEdition()
   Text1(17).Text = IsWinXPSP2()
   
   Text1(18).Text = IsWinXPMediaCenter()
   Text1(19).Text = IsWinXPStarter()
   Text1(20).Text = IsWinXPTabletPc()
   Text1(21).Text = IsWinXPEmbedded()
   
   Text1(22).Text = IsWinXP64()
   
   Text1(23).Text = IsWinVista()
   Text1(24).Text = IsWinVistaPlus()
   
   Text1(25).Text = IsWinVistaHomeBasic
   Text1(26).Text = IsWinVistaHomePremium
   Text1(27).Text = IsWinVistaBusiness
   Text1(28).Text = IsWinVistaEnterprise
   Text1(29).Text = IsWinVistaUltimate
   Text1(30).Text = IsWinVistaHomeServer
   Text1(31).Text = IsWinVistaSP1
   
   Text1(32).Text = IsWin2003Server()
   Text1(33).Text = IsWin2003ServerR2()
   
   Text1(34).Text = IsWinLonghornServer()
   
   Text1(35).Text = IsBackOfficeServer()
   Text1(36).Text = IsBladeServer()
   Text1(37).Text = IsDomainController()
   Text1(38).Text = IsEnterpriseServer()
   Text1(39).Text = IsSmallBusinessServer()
   Text1(40).Text = IsSmallBusinessRestrictedServer()
   Text1(41).Text = IsTerminalServer()

   For cnt = Text1.LBound To Text1.UBound
      If Text1(cnt).Text = "True" Then
         Text1(cnt).BackColor = vbYellow
         Label1(cnt).Font.Bold = True
      End If
   Next
   
End Sub

Private Function IsBackOfficeServer() As Boolean

   Dim osv As OSVERSIONINFOEX
  'Returns True if Microsoft BackOffice components are installed
  
  'OSVERSIONINFOEX supported on NT4 or
  'later only, so a test is required
  'before using
   If IsWinNT4Plus() Then
   
      osv.OSVSize = Len(osv)
   
      If GetVersionEx(osv) = 1 Then
         IsBackOfficeServer = (osv.wSuiteMask And VER_SUITE_BACKOFFICE)
      End If
   
   End If

End Function

Private Function IsBladeServer() As Boolean

   Dim osv As OSVERSIONINFOEX
  'Returns True if Windows Server 2003 Web Edition is installed
  
  'OSVERSIONINFOEX supported on NT4 or
  'later only, so a test is required
  'before using
   If IsWin2003Server() Then
   
      osv.OSVSize = Len(osv)
   
      If GetVersionEx(osv) = 1 Then
         IsBladeServer = (osv.wSuiteMask And VER_SUITE_BLADE)
      End If
   
   End If

End Function

Private Function IsDomainController() As Boolean
  
   Dim osv As OSVERSIONINFOEX
  'Returns True if the server is a domain
  'controller (Win 2000 or later), including
  'under active directory
   
  'OSVERSIONINFOEX supported on NT4 or
  'later only, so a test is required
  'before using
   If IsWin2000Server() Then
   
      osv.OSVSize = Len(osv)
      
      If GetVersionEx(osv) = 1 Then
      
         IsDomainController = (osv.wProductType = VER_NT_SERVER) And _
                              (osv.wProductType = VER_NT_DOMAIN_CONTROLLER)
       
      End If
   
   End If

End Function

Private Function IsEnterpriseServer() As Boolean

   Dim osv As OSVERSIONINFOEX
  'Returns True if Windows NT 4.0 Enterprise Edition,
  'Windows 2000 Advanced Server, or Windows Server 2003
  'Enterprise Edition is installed.
   
  'OSVERSIONINFOEX supported on NT4 or
  'later only, so a test is required
  'before using
   If IsWinNT4Plus() Then
   
      osv.OSVSize = Len(osv)
      
      If GetVersionEx(osv) = 1 Then
      
         IsEnterpriseServer = (osv.wProductType = VER_NT_SERVER) And _
                              (osv.wSuiteMask And VER_SUITE_ENTERPRISE)
          
      End If
   
   End If

End Function

Private Function IsSmallBusinessServer() As Boolean

   Dim osv As OSVERSIONINFOEX
  'Returns True if Microsoft Small Business Server is installed
  
  'OSVERSIONINFOEX supported on NT4 or
  'later only, so a test is required
  'before using
   If IsWinNT4Plus() Then
   
      osv.OSVSize = Len(osv)
   
      If GetVersionEx(osv) = 1 Then
         IsSmallBusinessServer = (osv.wSuiteMask And VER_SUITE_SMALLBUSINESS)
      End If
   
   End If

End Function

Private Function IsSmallBusinessRestrictedServer() As Boolean

   Dim osv As OSVERSIONINFOEX
  'Returns True if Microsoft Small Business Server
  'is installed with the restrictive client license
  'in force
  
  'OSVERSIONINFOEX supported on NT4 or
  'later only, so a test is required
  'before using
   If IsWinNT4Plus() Then
   
      osv.OSVSize = Len(osv)
   
      If GetVersionEx(osv) = 1 Then
         IsSmallBusinessRestrictedServer = (osv.wSuiteMask And VER_SUITE_SMALLBUSINESS_RESTRICTED)
      End If
   
   End If

End Function

Private Function IsTerminalServer() As Boolean
  
   Dim osv As OSVERSIONINFOEX
  'Returns True if Terminal Services is installed
   
  'OSVERSIONINFOEX supported on NT4 or
  'later only, so a test is required
  'before using
   If IsWinNT4Plus() Then
   
      osv.OSVSize = Len(osv)
      
      If GetVersionEx(osv) = 1 Then
         IsTerminalServer = (osv.wSuiteMask And VER_SUITE_TERMINAL)
      End If
   
   End If

End Function

Private Function IsWin95() As Boolean

  'returns True if running Windows 95
   Dim osv As OSVERSIONINFO

   osv.OSVSize = Len(osv)

   If GetVersionEx(osv) = 1 Then
   
      IsWin95 = (osv.PlatformID = VER_PLATFORM_WIN32_WINDOWS) And _
                (osv.dwVerMajor = 4 And osv.dwVerMinor = 0) And _
                (osv.dwBuildNumber = 950)
                
   End If

End Function

Private Function IsWin95OSR2() As Boolean

  'returns True if running Windows 95 OSR2 (OEM Service Release 2)
   Dim osv As OSVERSIONINFO

   osv.OSVSize = Len(osv)

   If GetVersionEx(osv) = 1 Then
   
      IsWin95OSR2 = (osv.PlatformID = VER_PLATFORM_WIN32_WINDOWS) And _
                    (osv.dwVerMajor = 4 And osv.dwVerMinor = 0) And _
                    (osv.dwBuildNumber = 1111)
 
   End If

End Function

Private Function IsWin98() As Boolean

  'returns True if running Windows 98
   Dim osv As OSVERSIONINFO

   osv.OSVSize = Len(osv)

   If GetVersionEx(osv) = 1 Then
   
      IsWin98 = (osv.PlatformID = VER_PLATFORM_WIN32_WINDOWS) And _
                (osv.dwVerMajor = 4 And osv.dwVerMinor = 10) And _
                (osv.dwBuildNumber >= 1998)
                
   End If

End Function

Private Function IsWinME() As Boolean

  'returns True if running Windows ME
   Dim osv As OSVERSIONINFO

   osv.OSVSize = Len(osv)

   If GetVersionEx(osv) = 1 Then
   
      IsWinME = (osv.PlatformID = VER_PLATFORM_WIN32_WINDOWS) And _
                (osv.dwVerMajor = 4 And osv.dwVerMinor = 90) And _
                (osv.dwBuildNumber >= 3000)
     
   End If

End Function

Private Function IsWinNT4() As Boolean

  'returns True if running Windows NT4
   Dim osv As OSVERSIONINFO

   osv.OSVSize = Len(osv)

   If GetVersionEx(osv) = 1 Then
   
      IsWinNT4 = (osv.PlatformID = VER_PLATFORM_WIN32_NT) And _
                 (osv.dwVerMajor = 4 And osv.dwVerMinor = 0) And _
                 (osv.dwBuildNumber >= 1381)
                 
   End If

End Function

Private Function IsWinNT4Plus() As Boolean

  'returns True if running Windows NT4 or later
   Dim osv As OSVERSIONINFO

   osv.OSVSize = Len(osv)

   If GetVersionEx(osv) = 1 Then
   
      IsWinNT4Plus = (osv.PlatformID = VER_PLATFORM_WIN32_NT) And _
                     (osv.dwVerMajor >= 4)
 
   End If

End Function

Private Function IsWinNT4Server() As Boolean

  'returns True if running Windows NT4 Server
   Dim osv As OSVERSIONINFOEX
      
   If IsWinNT4() Then
  
      osv.OSVSize = Len(osv)
   
      If GetVersionEx(osv) = 1 Then
      
         IsWinNT4Server = (osv.wProductType And VER_NT_SERVER)
         
      End If

   End If

End Function

Private Function IsWinNT4Workstation() As Boolean

  'returns True if running Windows NT4 Workstation
   Dim osv As OSVERSIONINFOEX
      
   If IsWinNT4() Then
  
      osv.OSVSize = Len(osv)
   
      If GetVersionEx(osv) = 1 Then
      
         IsWinNT4Workstation = (osv.wProductType And VER_NT_WORKSTATION)
         
      End If

   End If

End Function

Private Function IsWin2000() As Boolean

  'returns True if running Windows 2000 (NT5)
   Dim osv As OSVERSIONINFO

   osv.OSVSize = Len(osv)

   If GetVersionEx(osv) = 1 Then
   
      IsWin2000 = (osv.PlatformID = VER_PLATFORM_WIN32_NT) And _
                  (osv.dwVerMajor = 5 And osv.dwVerMinor = 0) And _
                  (osv.dwBuildNumber >= 2195)
                  
   End If

End Function

Private Function IsWin2000Plus() As Boolean

  'returns True if running Windows 2000 or later
   Dim osv As OSVERSIONINFO

   osv.OSVSize = Len(osv)

   If GetVersionEx(osv) = 1 Then
   
      IsWin2000Plus = (osv.PlatformID = VER_PLATFORM_WIN32_NT) And _
                      (osv.dwVerMajor => 5 And osv.dwVerMinor >= 0)
  
   End If

End Function

Private Function IsWin2000AdvancedServer() As Boolean

   Dim osv As OSVERSIONINFOEX
  'Returns True if Windows 2000 Advanced Server
   
  'OSVERSIONINFOEX supported on NT4 or
  'later only, so a test is required
  'before using
   If IsWin2000Plus() Then
   
      osv.OSVSize = Len(osv)
      
      If GetVersionEx(osv) = 1 Then
      
         IsWin2000AdvancedServer = ((osv.wProductType = VER_NT_SERVER) Or _
                                    (osv.wProductType = VER_NT_DOMAIN_CONTROLLER)) And _
                                    (osv.wSuiteMask And VER_SUITE_ENTERPRISE)
      End If
   
   End If

End Function

Private Function IsWin2000Server() As Boolean

   Dim osv As OSVERSIONINFOEX
  'Returns True if Windows 2000 Server
   
  'OSVERSIONINFOEX supported on NT4 or
  'later only, so a test is required
  'before using
   If IsWin2000() Then
   
      osv.OSVSize = Len(osv)
      
      If GetVersionEx(osv) = 1 Then
      
         IsWin2000Server = (osv.wProductType = VER_NT_SERVER)
         
      End If
   
   End If

End Function

Private Function IsWin2000Workstation() As Boolean

  'returns True if running Windows NT4 Workstation
   Dim osv As OSVERSIONINFOEX
      
   If IsWin2000() Then
  
      osv.OSVSize = Len(osv)
   
      If GetVersionEx(osv) = 1 Then
      
         IsWin2000Workstation = (osv.wProductType And VER_NT_WORKSTATION)
         
      End If

   End If

End Function

Private Function IsWin2003Server() As Boolean

  'returns True if running Windows 2003 (.NET) Server
   Dim osv As OSVERSIONINFO

   osv.OSVSize = Len(osv)

   If GetVersionEx(osv) = 1 Then
   
      IsWin2003Server = (osv.PlatformID = VER_PLATFORM_WIN32_NT) And _
                        (osv.dwVerMajor = 5 And osv.dwVerMinor = 2) And _
                        (osv.dwBuildNumber = 3790)

   End If

End Function

Private Function IsWin2003ServerR2() As Boolean
 
  'returns True if running
  'Windows 2003 (.NET) Server Release 2
   If IsWin2003Server() Then
   
      IsWin2003ServerR2 = GetSystemMetrics(SM_SERVERR2)
   
   End If
 
End Function

Private Function IsWinXP() As Boolean

  'returns True if running Windows XP
   Dim osv As OSVERSIONINFO

   osv.OSVSize = Len(osv)

   If GetVersionEx(osv) = 1 Then
   
      IsWinXP = (osv.PlatformID = VER_PLATFORM_WIN32_NT) And _
                (osv.dwVerMajor = 5 And osv.dwVerMinor = 1) And _
                (osv.dwBuildNumber >= 2600)

   End If

End Function

Private Function IsWinXPSP2() As Boolean

  'returns True if running Windows XP SP2 (Service Pack 2)
   Dim osv As OSVERSIONINFOEX
      
   If IsWinXP() Then
  
      osv.OSVSize = Len(osv)
   
      If GetVersionEx(osv) = 1 Then
      
         IsWinXPSP2 = InStr(osv.szCSDVersion, "Service Pack 2") > 0
      
      End If

   End If

End Function

Private Function IsWinXPPlus() As Boolean

  'returns True if running Windows XP or later
   Dim osv As OSVERSIONINFO

   osv.OSVSize = Len(osv)

   If GetVersionEx(osv) = 1 Then
   
      IsWinXPPlus = (osv.PlatformID = VER_PLATFORM_WIN32_NT) And _
                    ((osv.dwVerMajor >= 5 And osv.dwVerMinor >= 1) Or _
                    (osv.dwVerMajor >= 6 And osv.dwVerMinor >= 0))

   End If

End Function

Private Function IsWinXPHomeEdition() As Boolean

  'returns True if running Windows XP Home Edition
   Dim osv As OSVERSIONINFOEX
      
   If IsWinXP() Then
  
      osv.OSVSize = Len(osv)
   
      If GetVersionEx(osv) = 1 Then
      
         IsWinXPHomeEdition = ((osv.wSuiteMask And VER_SUITE_PERSONAL) = VER_SUITE_PERSONAL)
         
      End If

   End If

End Function

Private Function IsWinXPProEdition() As Boolean

  'returns True if running Windows XP Pro
   Dim osv As OSVERSIONINFOEX
      
   If IsWinXP() Then
  
      osv.OSVSize = Len(osv)
   
      If GetVersionEx(osv) = 1 Then
      
         IsWinXPProEdition = Not ((osv.wSuiteMask And VER_SUITE_PERSONAL) = VER_SUITE_PERSONAL)
      
      End If

   End If

End Function

Private Function IsWinXPMediaCenter() As Boolean
 
  'returns True if running Windows XP Media Centre
   If IsWinXP() Then
   
      IsWinXPMediaCenter = GetSystemMetrics(SM_MEDIACENTER)
   
   End If
 
End Function

Private Function IsWinXPStarter() As Boolean
 
  'returns True if running Windows XP Starter
   If IsWinXP() Then
   
      IsWinXPStarter = GetSystemMetrics(SM_STARTER)
   
   End If
 
End Function

Private Function IsWinXPTabletPc() As Boolean
 
  'returns True if running Windows XP Tablet Pc
   If IsWinXP() Then
   
      IsWinXPTabletPc = GetSystemMetrics(SM_TABLETPC)
   
   End If
 
End Function


Private Function IsWinXPEmbedded() As Boolean

  'Returns True if OS is Windows XP Embedded
   Dim osv As OSVERSIONINFOEX
  
  'OSVERSIONINFOEX supported on NT4 or
  'later only, so a test is required
  'before using
   If IsWinXP() Then
   
      osv.OSVSize = Len(osv)
   
      If GetVersionEx(osv) = 1 Then
         IsWinXPEmbedded = (osv.wSuiteMask And VER_SUITE_EMBEDDEDNT)
      End If
   
   End If

End Function

Private Function IsWinXP64() As Boolean

  'returns True if running Windows XP 64-bit
   Dim osv As OSVERSIONINFOEX
   Dim si As SYSTEM_INFO
   
   osv.OSVSize = Len(osv)

   If GetVersionEx(osv) = 1 Then
   
      GetSystemInfo si
        'PLEASE SEE THE COMMENTS SECTION AT THE BOTTOM 
        'OF THIS PAGE IF YOU ARE RUNNING WINDOWS 64-BIT
        'IsWinXP64 = (osv.PlatformID = VER_PLATFORM_WIN32_NT) And _
                     (osv.dwVerMajor = 5 And osv.dwVerMinor = 2) And _
                     (osv.wProductType <> VER_NT_WORKSTATION) And _
                     (si.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_IA64)
      
   End If

End Function

Private Function IsWinVista() As Boolean

  'returns True if running Windows Vista
   Dim osv As OSVERSIONINFO

   osv.OSVSize = Len(osv)

   If GetVersionEx(osv) = 1 Then
   
      IsWinVista = (osv.PlatformID = VER_PLATFORM_WIN32_NT) And _
                   (osv.dwVerMajor = 6)

   End If
   
End Function

Private Function IsWinVistaPlus() As Boolean

  'returns True if running Windows Vista or later
   Dim osv As OSVERSIONINFO

   osv.OSVSize = Len(osv)

   If GetVersionEx(osv) = 1 Then
   
      IsWinVistaPlus = (osv.PlatformID = VER_PLATFORM_WIN32_NT) And _
                   (osv.dwVerMajor >= 6)

   End If
   
End Function

Private Function IsWinVistaSP1() As Boolean

  'returns True if running any Windows Vista version with SP1 applied
   Dim osv As OSVERSIONINFO

   osv.OSVSize = Len(osv)

   If GetVersionEx(osv) = 1 Then
   
      IsWinVistaSP1 = (osv.PlatformID = VER_PLATFORM_WIN32_NT) And _
                      (osv.dwVerMajor = 6) And _
                      InStr(osv.szCSDVersion, "Service Pack 1") > 0

   End If
   
End Function

Private Function IsWinVistaBusiness() As Boolean

  'returns True if running Windows Vista Business
   Dim osv As OSVERSIONINFO
   Dim dwProduct As Long


   If IsWinVista() Then
   
      osv.OSVSize = Len(osv)
      GetVersionEx osv
      
      If GetProductInfo(osv.dwVerMajor, osv.dwVerMinor, 0&, 0&, dwProduct) <> 0 Then
      
         IsWinVistaBusiness = (dwProduct = PRODUCT_BUSINESS) Or _
                              (dwProduct = PRODUCT_BUSINESS_N)
           
      End If  'GetProductInfo
         
   End If  'IsWinVista
   
End Function

Private Function IsWinVistaUltimate() As Boolean

  'returns True if running Windows Vista Ultimate
   Dim osv As OSVERSIONINFO
   Dim dwProduct As Long


   If IsWinVista() Then
   
      osv.OSVSize = Len(osv)
      GetVersionEx osv
      
      If GetProductInfo(osv.dwVerMajor, osv.dwVerMinor, 0&, 0&, dwProduct) <> 0 Then
      
         IsWinVistaUltimate = (dwProduct = PRODUCT_ULTIMATE) Or _
                              (dwProduct = PRODUCT_ULTIMATE_N)
           
      End If  'GetProductInfo
         
   End If  'IsWinVista
   
End Function

Private Function IsWinVistaHomeServer() As Boolean

  'returns True if running Windows Vista Home Server
   Dim osv As OSVERSIONINFO
   Dim dwProduct As Long


   If IsWinVista() Then
   
      osv.OSVSize = Len(osv)
      GetVersionEx osv
      
      If GetProductInfo(osv.dwVerMajor, osv.dwVerMinor, 0&, 0&, dwProduct) <> 0 Then
      
         IsWinVistaHomeServer = (dwProduct = PRODUCT_HOME_SERVER)
           
      End If  'GetProductInfo
         
   End If  'IsWinVista
   
End Function

Private Function IsWinVistaHomeBasic() As Boolean

  'returns True if running Windows Vista Home Basic
   Dim osv As OSVERSIONINFO
   Dim dwProduct As Long


   If IsWinVista() Then
   
      osv.OSVSize = Len(osv)
      GetVersionEx osv
      
      If GetProductInfo(osv.dwVerMajor, osv.dwVerMinor, 0&, 0&, dwProduct) <> 0 Then
      
         IsWinVistaHomeBasic = (dwProduct = PRODUCT_HOME_BASIC) Or _
                               (dwProduct = PRODUCT_HOME_BASIC_N)
           
      End If  'GetProductInfo
         
   End If  'IsWinVista
   
End Function

Private Function IsWinVistaHomePremium() As Boolean

  'returns True if running Windows Vista Home Premium
   Dim osv As OSVERSIONINFO
   Dim dwProduct As Long


   If IsWinVista() Then
   
      osv.OSVSize = Len(osv)
      GetVersionEx osv
      
      If GetProductInfo(osv.dwVerMajor, osv.dwVerMinor, 0&, 0&, dwProduct) <> 0 Then
      
         IsWinVistaHomePremium = (dwProduct = PRODUCT_HOME_PREMIUM) Or _
                                 (dwProduct = PRODUCT_HOME_PREMIUM_N)
           
      End If  'GetProductInfo
         
   End If  'IsWinVista
   
End Function

Private Function IsWinVistaEnterprise() As Boolean

  'returns True if running Windows Vista Enterprise
   Dim osv As OSVERSIONINFO
   Dim dwProduct As Long


   If IsWinVista() Then
   
      osv.OSVSize = Len(osv)
      GetVersionEx osv
      
      If GetProductInfo(osv.dwVerMajor, osv.dwVerMinor, 0&, 0&, dwProduct) <> 0 Then
      
         IsWinVistaEnterprise = (dwProduct = PRODUCT_ENTERPRISE) Or _
                                (dwProduct = PRODUCT_ENTERPRISE_N)
           
      End If  'GetProductInfo
         
   End If  'IsWinVista
   
End Function

Private Function IsWinLonghornServer() As Boolean

  'returns True if running Windows Longhorn Server
   Dim osv As OSVERSIONINFOEX

   osv.OSVSize = Len(osv)

   If GetVersionEx(osv) = 1 Then
   
      IsWinLonghornServer = (osv.PlatformID = VER_PLATFORM_WIN32_NT) And _
                            (osv.dwVerMajor = 6 And osv.dwVerMinor = 0) And _
                            (osv.wProductType <> VER_NT_WORKSTATION)

   End If

End Function
 Comments
Running the project will populate the appropriate text boxes with True, indicating the current platform tests.

ELICITING HELP FROM WINDOWS 64-BIT USERS
The SYSTEM_INFO parameter dwOemID is defined in the MSDN as a UNION which VB does not directly support. This definition splits dwOemID, a Long, into two Integer members -- wProcessorArchitecture and wReserved.

The IsWinXP64 test requires testing of wProcessorArchitecture as part of the OS version determination. As I am running Win32 and not Win64 I am unable to test how to declare SYSTEM_INFO in order to return the correct value to test for 64-bit Windows. Therefore I am eliciting the help of 64-bit Windows users as testers.

There are three possibilities I can think of that will allow Win64 users to utilize the SYSTEM_INFO struct: test the high and low words comprising dwOemID as defined in the original SYSTEM_INFO structure; redefine the structure to add two Integers as the first two members rather than the dwOemID Long, and finally to define an Integer structure for use in place of the dwOemID member.

In my tests her on Win32, none of these options causes the call to GetSystemInfo to fail. Therefore it is possible that any or all of these three variations will provide the desired data under 64-bit Windows. I would like to ask those of you who are running XP 64-bit to create the following demo for me and email me (using the Comments link in the navigation bar) with the method(s) that work under Win64.

All the code below can be placed on a new form with a single button; the output is thrown to the debug window. If a particular method works you should see a non-zero value for the parameter testing for the wProcessorArchitecture member.
 


'API redefined As Any to accommodate SYSTEM_INFO variations below
Private Declare Sub GetSystemInfo Lib "kernel32" _
   (lpSystemInfo As Any)
   
   
'A)  testing the high and low words comprising dwOemID when Long 

Private Type SYSTEM_INFO_A
   dwOemID As Long
   dwPageSize As Long
   lpMinimumApplicationAddress As Long
   lpMaximumApplicationAddress As Long
   dwActiveProcessorMask As Long
   dwNumberOfProcessors As Long
   dwProcessorType As Long
   dwAllocationGranularity As Long
   wProcessorLevel As Integer
   wProcessorRevision As Integer
End Type


'B)  redefining the structure to split the Long into two Integers 

Private Type SYSTEM_INFO_B
   wProcessorArchitecture As Integer
   wReserved As Integer
   dwPageSize As Long
   lpMinimumApplicationAddress As Long
   lpMaximumApplicationAddress As Long
   dwActiveProcessorMask As Long
   dwNumberOfProcessors As Long
   dwProcessorType As Long
   dwAllocationGranularity As Long
   wProcessorLevel As Integer
   wProcessorRevision As Integer
End Type


'C)  utilizing a second Integer structure 

Private Type OEM_UNION
   wProcessorArchitecture As Integer
   wReserved As Integer
End Type

Private Type SYSTEM_INFO_C
   dwOemID As OEM_UNION
   dwPageSize As Long
   lpMinimumApplicationAddress As Long
   lpMaximumApplicationAddress As Long
   dwActiveProcessorMask As Long
   dwNumberOfProcessors As Long
   dwProcessorType As Long
   dwAllocationGranularity As Long
   wProcessorLevel As Integer
   wProcessorRevision As Integer
End Type


' TESTING CODE

Private Sub Command1_Click()

   dim siA as SYSTEM_INFO_A
   dim siB as SYSTEM_INFO_B
   dim siC as SYSTEM_INFO_C

   GetSystemInfo siA
   debug.print loword(siA.dwOemId), hiword(siA.dwOemId)

   GetSystemInfo siB
   debug.print siB.wProcessorArchitecture, siB.wReserved

   GetSystemInfo siC
   debug.print siC.dwOemID.wProcessorArchitecture, siC.dwOemID.wReserved

End Sub

'SUPPORT ROUTINES FOR METHOD A

Private Function HiWord(wParam As Long) As Integer

   If wParam And &H80000000 Then
      HiWord = (wParam \ 65535) - 1
   Else
      HiWord = wParam \ 65535
   End If

End Function

Private Function LoWord(wParam As Long) As Integer

   If wParam And &H8000& Then
      LoWord = &H8000& Or (wParam And &H7FFF&)
   Else
      LoWord = wParam And &HFFFF&
   End If

End Function

 
 

PayPal Link
Make payments with PayPal - it's fast, free and secure!

 
 
 
 

Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy

 

 

Hit Counter