区分 Windows Server 2016 和 2019 的不同之处

3

我所要做的是,使用rtlGetVersion确定Windows Server 2016和2019之间的差异,使用版本号(如1803/1809),而不是最新版本号。


我正在修复我们旧代码中使用GetVersionEx的问题,转而使用rltGetVersion。大部分代码已经写好了,只需要实现它就可以了。使用这个链接:如何确定VB 6应用程序是否在Windows 10上运行?

问题是,Windows Server 2016和19具有相同的字段,因此无法通过此设置来确定它是哪一个。根据https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions,我知道Windows Server 2016的版本为1803,而2019的版本为1809。

我遇到的问题是,使用rltGetVersion创建了一个类似于以下结构的结构体。https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/ns-wdm-_osversioninfoexw

而最接近的是构建号,但那会发生变化。我想知道是否有人知道如何获取构建版本而不是构建号,如果这有意义的话。

这是来自第一个链接的代码:

'==================================================================================
' RealWinVer.bas     by Cody Gray, 2016
' 
' (Freely available for use and modification, provided that credit is given to the
' original author. Including a comment in the code with my name and/or a link to
' this Stack Overflow answer is sufficient.)
'==================================================================================

Option Explicit

''''''''''''''''''''''''''''''''''''''''''''''''''
' Windows SDK Constants, Types, & Functions
''''''''''''''''''''''''''''''''''''''''''''''''''

Private Const cbCSDVersion As Long = 128 * 2

Private Const STATUS_SUCCESS As Long = 0

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

Private Const VER_NT_WORKSTATION As Byte       = 1
Private Const VER_NT_DOMAIN_CONTROLLER As Byte = 2
Private Const VER_NT_SERVER As Byte            = 3

Private Const VER_SUITE_PERSONAL As Integer = &H200

Private Type RTL_OSVERSIONINFOEXW
   dwOSVersionInfoSize As Long
   dwMajorVersion      As Long
   dwMinorVersion      As Long
   dwBuildNumber       As Long
   dwPlatformId        As Long
   szCSDVersion        As String * cbCSDVersion
   wServicePackMajor   As Integer
   wServicePackMinor   As Integer
   wSuiteMask          As Integer
   wProductType        As Byte
   wReserved           As Byte
End Type

Private Declare Function RtlGetVersion Lib "ntdll" _
    (lpVersionInformation As RTL_OSVERSIONINFOEXW) As Long


''''''''''''''''''''''''''''''''''''''''''''''''''
' Internal Helper Functions
''''''''''''''''''''''''''''''''''''''''''''''''''

Private Function IsWinServerVersion(ByRef ver As RTL_OSVERSIONINFOEXW) As Boolean
   ' There are three documented values for "wProductType".
   ' Two of the values mean that the OS is a server versions,
   ' while the other value signifies a home/workstation version.
   Debug.Assert ver.wProductType = VER_NT_WORKSTATION Or _
                ver.wProductType = VER_NT_DOMAIN_CONTROLLER Or _
                ver.wProductType = VER_NT_SERVER

   IsWinServerVersion = (ver.wProductType <> VER_NT_WORKSTATION)
End Function

Private Function GetWinVerNumber(ByRef ver As RTL_OSVERSIONINFOEXW) As String
   Debug.Assert ver.dwPlatformId = VER_PLATFORM_WIN32_NT

   GetWinVerNumber = ver.dwMajorVersion & "." & _
                     ver.dwMinorVersion & "." & _
                     ver.dwBuildNumber
End Function

Private Function GetWinSPVerNumber(ByRef ver As RTL_OSVERSIONINFOEXW) As String
   Debug.Assert ver.dwPlatformId = VER_PLATFORM_WIN32_NT

   If (ver.wServicePackMajor > 0) Then
      If (ver.wServicePackMinor > 0) Then
         GetWinSPVerNumber = "SP" & CStr(ver.wServicePackMajor) & "." & CStr(ver.wServicePackMinor)
         Exit Function
      Else
         GetWinSPVerNumber = "SP" & CStr(ver.wServicePackMajor)
         Exit Function
      End If
   End If
End Function

Private Function GetWinVerName(ByRef ver As RTL_OSVERSIONINFOEXW) As String
   Debug.Assert ver.dwPlatformId = VER_PLATFORM_WIN32_NT

   Select Case ver.dwMajorVersion
      Case 3
         If IsWinServerVersion(ver) Then
            GetWinVerName = "Windows NT 3.5 Server"
            Exit Function
         Else
            GetWinVerName = "Windows NT 3.5 Workstation"
            Exit Function
         End If
      Case 4
         If IsWinServerVersion(ver) Then
            GetWinVerName = "Windows NT 4.0 Server"
            Exit Function
         Else
            GetWinVerName = "Windows NT 4.0 Workstation"
            Exit Function
         End If
      Case 5
         Select Case ver.dwMinorVersion
            Case 0
               If IsWinServerVersion(ver) Then
                  GetWinVerName = "Windows 2000 Server"
                  Exit Function
               Else
                  GetWinVerName = "Windows 2000 Workstation"
                  Exit Function
               End If
            Case 1
               If (ver.wSuiteMask And VER_SUITE_PERSONAL) Then
                  GetWinVerName = "Windows XP Home Edition"
                  Exit Function
               Else
                  GetWinVerName = "Windows XP Professional"
                  Exit Function
               End If
            Case 2
               If IsWinServerVersion(ver) Then
                  GetWinVerName = "Windows Server 2003"
                  Exit Function
               Else
                  GetWinVerName = "Windows XP 64-bit Edition"
                  Exit Function
               End If
            Case Else
               Debug.Assert False
         End Select
      Case 6
         Select Case ver.dwMinorVersion
            Case 0
               If IsWinServerVersion(ver) Then
                  GetWinVerName = "Windows Server 2008"
                  Exit Function
               Else
                  GetWinVerName = "Windows Vista"
                  Exit Function
               End If
            Case 1
               If IsWinServerVersion(ver) Then
                  GetWinVerName = "Windows Server 2008 R2"
                  Exit Function
               Else
                  GetWinVerName = "Windows 7"
                  Exit Function
               End If
            Case 2
               If IsWinServerVersion(ver) Then
                  GetWinVerName = "Windows Server 2012"
                  Exit Function
               Else
                  GetWinVerName = "Windows 8"
                  Exit Function
               End If
            Case 3
               If IsWinServerVersion(ver) Then
                  GetWinVerName = "Windows Server 2012 R2"
                  Exit Function
               Else
                  GetWinVerName = "Windows 8.1"
                  Exit Function
               End If
            Case Else
               Debug.Assert False
         End Select
      Case 10
         If IsWinServerVersion(ver) Then
            GetWinVerName = "Windows Server 2016"
            Exit Function
         Else
            GetWinVerName = "Windows 10"
            Exit Function
         End If
      Case Else
         Debug.Assert False
   End Select

   GetWinVerName = "Unrecognized Version"
End Function


''''''''''''''''''''''''''''''''''''''''''''''''''
' Public Functions
''''''''''''''''''''''''''''''''''''''''''''''''''

' Returns a string that contains the name of the underlying version of Windows,
' the major version of the most recently installed service pack, and the actual
' version number (in "Major.Minor.Build" format).
'
' For example: "Windows Server 2003 SP2 (v5.2.3790)" or
'              "Windows 10 (v10.0.14342)"
'
' This function returns the *real* Windows version, and works correctly on all
' operating systems, including Windows 10, regardless of whether or not the
' application includes a manifest. It calls the native NT version-info function
' directly in order to bypass compatibility shims that would otherwise lie to
' you about the real version number.
Public Function GetActualWindowsVersion() As String
   Dim ver As RTL_OSVERSIONINFOEXW
   ver.dwOSVersionInfoSize = Len(ver)

   If (RtlGetVersion(ver) <> STATUS_SUCCESS) Then
      GetActualWindowsVersion = "Failed to retrieve Windows version"
   End If

   ' The following version-parsing logic assumes that the operating system
   ' is some version of Windows NT. This assumption will be true if you
   ' are running any version of Windows released in the past 15 years,
   ' including several that were released before that.
   Debug.Assert ver.dwPlatformId = VER_PLATFORM_WIN32_NT

   GetActualWindowsVersion = GetWinVerName(ver) & " " & GetWinSPVerNumber(ver) & _
                             " (v" & GetWinVerNumber(ver) & ")"
End Function
1个回答

2

只需比较版本号即可知道 Windows 10 的版本。版本号是您唯一可以查看的内容,无法从 Windows 10 获取“版本”字符串。Windows Server 2019 的构建号将大于或等于17623,任何小于此构建号的都将是 Windows Server 2016。


你的意思是17763吗?另外,如果Windows Server 2016有更新,那么Windows 2016的构建版本号会大于17763吗? - Ram Kishore K

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接