Jump to content

@OSVersion on Windows 10 recognized as Windows 8.1 when compiled


Recommended Posts

How about this workaround? Can anyone with Win10 please confirm that this function returns 0x0604, regardless of the manifest?

Local $iWinVer = __WINVER_Kernel()

If $iWinVer >= 0x0601 Then ; Current OS is Win7 or newer
    ConsoleWrite("+" & @TAB & $iWinVer & @CRLF)
Else
    ConsoleWrite("-" & @TAB & $iWinVer & @CRLF)
EndIf

Func __WINVER_Kernel()
    ; GetVersionEx
    ; https://msdn.microsoft.com/de-de/library/windows/desktop/ms724451(v=vs.85).aspx
    ; With the release of Windows 8.1, the behavior of the GetVersionEx API has changed in the value it will return for the operating system version.
    ; The value returned by the GetVersionEx function now depends on how the application is manifested.

    ; If you don't want to depend on manifests and reply on this deprecated API, use kernel-mode RtlGetVersion:
    ; https://msdn.microsoft.com/en-us/library/windows/hardware/ff561910(v=vs.85).aspx

    Local $tOSVI = DllStructCreate('dword;dword;dword;dword;dword;wchar[128]')
    DllStructSetData($tOSVI, 1, DllStructGetSize($tOSVI))
    Local $Ret = DllCall("ntdll.dll", "int", "RtlGetVersion", "ptr", DllStructGetPtr($tOSVI))
    If @error Or $Ret[0] <> 0 Then Return SetError(1, 0, 0) ; RtlGetVersion returns STATUS_SUCCESS = 0

    ; 0x0501 = Win XP
    ; 0x0502 = Win Server 2003
    ; 0x0600 = Win Vista
    ; 0x0601 = Win7
    ; 0x0602 = Win8
    ; 0x0603 = Win8.1
    ; 0x0604 = Win10

    Return "0x" & Hex(BitOR(BitShift(DllStructGetData($tOSVI, 2), -8), DllStructGetData($tOSVI, 3)), 4)
EndFunc   ;==>__WINVER_Kernel

 

Link to comment
Share on other sites

Windows 10 Pro, build 10240 (running as VM, of course).

AutoIt v3.3.14.1

all results +0x0A00

tested: (1) uncompiled, (2) compiled without pragma compatilbility Win10, (3) compiled with pragma compatilbility Win10

EDIT: same tests indicate 0x0601 on Windows 7.

EDIT: 0x0604 (=6.4) is the "Technical Preview". 0x0A00 (=10.0) is the RTM (build 10240 or later)

EDIT: the registry still insists on 6.3 - Boo! WTF MS couldn't just put things right?! what's wrong with them?! :ranting:

Edited by orbs

Signature - my forum contributions:

Spoiler

UDF:

LFN - support for long file names (over 260 characters)

InputImpose - impose valid characters in an input control

TimeConvert - convert UTC to/from local time and/or reformat the string representation

AMF - accept multiple files from Windows Explorer context menu

DateDuration -  literal description of the difference between given dates

Apps:

Touch - set the "modified" timestamp of a file to current time

Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes

SPDiff - Single-Pane Text Diff

 

Link to comment
Share on other sites

Thanks for testing, the result is correct, my assumption was wrong :). Windows 10 replies to this call with MajorVersion = 10 and MinorVersion = 0, which sums up to 0x0A00. Win7 replies with MajorVersion = 6 and MinorVersion = 1, which sums up to 0x0601.

 

Edit: Please re-test with updated function attached, should show the difference under the scenarios you've tested above.

Edit-2: Good info on the technical preview and RTM, added to documentation of function :)...

 

ConsoleWrite((0x0A00 > 0x0601) & @CRLF)

Local $__WINVER_GetVersionExW = "0x" & Hex(__WINVER_GetVersionExW(), 4)
Local $__WINVER_RtlGetVersion = __WINVER_RtlGetVersion()

ConsoleWrite("$__WINVER_GetVersionExW" & @TAB & @TAB & $__WINVER_GetVersionExW & @CRLF)
ConsoleWrite("$__WINVER_RtlGetVersion" & @TAB & @TAB & $__WINVER_RtlGetVersion & @CRLF)

If $__WINVER_RtlGetVersion >= 0x0604 Then ; Current OS is "Win10 - Technical Preview" or up
    ConsoleWrite("+" & @TAB & $__WINVER_RtlGetVersion & @CRLF)
Else
    ConsoleWrite("-" & @TAB & $__WINVER_RtlGetVersion & @CRLF)
EndIf

Func __WINVER_RtlGetVersion()
    ; GetVersionEx
    ; https://msdn.microsoft.com/de-de/library/windows/desktop/ms724451(v=vs.85).aspx
    ; With the release of Windows 8.1, the behavior of the GetVersionEx API has changed in the value it will return for the operating system version.
    ; The value returned by the GetVersionEx function now depends on how the application is manifested.

    ; If you don't want to depend on manifests and reply on this deprecated API, use kernel-mode RtlGetVersion:
    ; https://msdn.microsoft.com/en-us/library/windows/hardware/ff561910(v=vs.85).aspx

    #cs
        typedef struct _OSVERSIONINFOW {
        ULONG dwOSVersionInfoSize;
        ULONG dwMajorVersion;
        ULONG dwMinorVersion;
        ULONG dwBuildNumber;
        ULONG dwPlatformId;
        WCHAR szCSDVersion[128];
        } RTL_OSVERSIONINFOW, *PRTL_OSVERSIONINFOW;
    #ce

    Local $tOSVI = DllStructCreate('dword;dword;dword;dword;dword;wchar[128]')
    DllStructSetData($tOSVI, 1, DllStructGetSize($tOSVI))
    Local $Ret = DllCall("ntdll.dll", "int", "RtlGetVersion", "ptr", DllStructGetPtr($tOSVI))
    If @error Or $Ret[0] <> 0 Then Return SetError(1, 0, 0) ; RtlGetVersion returns STATUS_SUCCESS = 0

    ; 0x0501 = Win XP
    ; 0x0502 = Win Server 2003
    ; 0x0600 = Win Vista
    ; 0x0601 = Win7 / Major Version = 6, Minor Version = 1
    ; 0x0602 = Win8
    ; 0x0603 = Win8.1
    ; 0x0604 = Win10 "Technical Preview"
    ; 0x0A00 = Win10 RTM (build 10240 or later) / Major Version = 10, Minor Version = 0

    ; Return "0x" & Hex(BitOR(BitShift(10, -8), 0), 4)
    Return "0x" & Hex(BitOR(BitShift(DllStructGetData($tOSVI, 2), -8), DllStructGetData($tOSVI, 3)), 4)
EndFunc   ;==>__WINVER_RtlGetVersion


Func __WINVER_GetVersionExW()
    Local $tOSVI = DllStructCreate('dword;dword;dword;dword;dword;wchar[128]')
    DllStructSetData($tOSVI, 1, DllStructGetSize($tOSVI))
    Local $Ret = DllCall('kernel32.dll', 'int', 'GetVersionExW', 'ptr', DllStructGetPtr($tOSVI))
    If (@error) Or (Not $Ret[0]) Then Return SetError(1, 0, 0)
    Return BitOR(BitShift(DllStructGetData($tOSVI, 2), -8), DllStructGetData($tOSVI, 3))
EndFunc   ;==>__WINVER_GetVersionExW

 

Edited by KaFu
Link to comment
Share on other sites

uncompiled & compiled without compatibility: both return 0x0A00

compiled with compatibility:

__WINVER_GetVersionExW returns 0x0603

__WINVER_RtlGetVersion returns 0x0A00

Signature - my forum contributions:

Spoiler

UDF:

LFN - support for long file names (over 260 characters)

InputImpose - impose valid characters in an input control

TimeConvert - convert UTC to/from local time and/or reformat the string representation

AMF - accept multiple files from Windows Explorer context menu

DateDuration -  literal description of the difference between given dates

Apps:

Touch - set the "modified" timestamp of a file to current time

Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes

SPDiff - Single-Pane Text Diff

 

Link to comment
Share on other sites

  • 4 years later...

RtlGetVersion also accepts $tagOSVERSIONINFOEX.

ConsoleWrite((0x0A00 > 0x0601) & @CRLF)

Local $__WINVER_GetVersionExW = "0x" & Hex(__WINVER_GetVersionExW(), 4)
Local $__WINVER_RtlGetVersion = __WINVER_RtlGetVersion()

ConsoleWrite("$__WINVER_GetVersionExW" & @TAB & @TAB & $__WINVER_GetVersionExW & @CRLF)
ConsoleWrite("$__WINVER_RtlGetVersion" & @TAB & @TAB & $__WINVER_RtlGetVersion & @CRLF)

If $__WINVER_RtlGetVersion >= 0x0604 Then ; Current OS is "Win10 - Technical Preview" or up
    ConsoleWrite("+" & @TAB & $__WINVER_RtlGetVersion & @CRLF)
Else
    ConsoleWrite("-" & @TAB & $__WINVER_RtlGetVersion & @CRLF)
EndIf

Func __WINVER_RtlGetVersion()
    ; GetVersionEx
    ; https://msdn.microsoft.com/de-de/library/windows/desktop/ms724451(v=vs.85).aspx
    ; With the release of Windows 8.1, the behavior of the GetVersionEx API has changed in the value it will return for the operating system version.
    ; The value returned by the GetVersionEx function now depends on how the application is manifested.

    ; If you don't want to depend on manifests and reply on this deprecated API, use kernel-mode RtlGetVersion:
    ; https://msdn.microsoft.com/en-us/library/windows/hardware/ff561910(v=vs.85).aspx

    Local Const $tOSVERSIONINFO = 'struct;dword OSVersionInfoSize;dword MajorVersion;dword MinorVersion;dword BuildNumber;dword PlatformId;wchar CSDVersion[128];endstruct'
    Local Const $tOSVERSIONINFOEX = $tOSVERSIONINFO & ';ushort ServicePackMajor;ushort ServicePackMinor;ushort SuiteMask;byte ProductType;byte Reserved'

    Local $tOSVI = DllStructCreate($tOSVERSIONINFOEX)
    DllStructSetData($tOSVI, 1, DllStructGetSize($tOSVI))
    Local $Ret = DllCall("ntdll.dll", "int", "RtlGetVersion", "ptr", DllStructGetPtr($tOSVI))
    If @error Or $Ret[0] <> 0 Then Return SetError(1, 0, 0) ; RtlGetVersion returns STATUS_SUCCESS = 0

    ConsoleWrite("MajorVersion=" & DllStructGetData($tOSVI,"MajorVersion") & @crlf)
    ConsoleWrite("MinorVersion=" & DllStructGetData($tOSVI,"MinorVersion") & @crlf)
    ConsoleWrite("ProductType=" & DllStructGetData($tOSVI,"ProductType") & @crlf)

    ; 0x0501 = Win XP
    ; 0x0502 = Win Server 2003
    ; 0x0600 = Win Vista
    ; 0x0601 = Win7 / Major Version = 6, Minor Version = 1
    ; 0x0602 = Win8
    ; 0x0603 = Win8.1
    ; 0x0604 = Win10 "Technical Preview"
    ; 0x0A00 = Win10 RTM (build 10240 or later) / Major Version = 10, Minor Version = 0

    ; Return "0x" & Hex(BitOR(BitShift(10, -8), 0), 4)
    Return "0x" & Hex(BitOR(BitShift(DllStructGetData($tOSVI, 2), -8), DllStructGetData($tOSVI, 3)), 4)
EndFunc   ;==>__WINVER_RtlGetVersion


Func __WINVER_GetVersionExW()
    Local $tOSVI = DllStructCreate('dword;dword;dword;dword;dword;wchar[128]')
    DllStructSetData($tOSVI, 1, DllStructGetSize($tOSVI))
    Local $Ret = DllCall('kernel32.dll', 'int', 'GetVersionExW', 'ptr', DllStructGetPtr($tOSVI))
    If (@error) Or (Not $Ret[0]) Then Return SetError(1, 0, 0)
    Return BitOR(BitShift(DllStructGetData($tOSVI, 2), -8), DllStructGetData($tOSVI, 3))
EndFunc   ;==>__WINVER_GetVersionExW

 

Edited by KaFu
Link to comment
Share on other sites

Don't have Win2000 at hand. The only difference I can think of is the missing include in 3.3.6.1, try this:

ConsoleWrite((0x0A00 > 0x0601) & @CRLF)

Local $__WINVER_GetVersionExW = "0x" & Hex(__WINVER_GetVersionExW(), 4)
Local $__WINVER_RtlGetVersion = __WINVER_RtlGetVersion()

ConsoleWrite("$__WINVER_GetVersionExW" & @TAB & @TAB & $__WINVER_GetVersionExW & @CRLF)
ConsoleWrite("$__WINVER_RtlGetVersion" & @TAB & @TAB & $__WINVER_RtlGetVersion & @CRLF)

If $__WINVER_RtlGetVersion >= 0x0604 Then ; Current OS is "Win10 - Technical Preview" or up
    ConsoleWrite("+" & @TAB & $__WINVER_RtlGetVersion & @CRLF)
Else
    ConsoleWrite("-" & @TAB & $__WINVER_RtlGetVersion & @CRLF)
EndIf

Func __WINVER_RtlGetVersion()
    ; GetVersionEx
    ; https://msdn.microsoft.com/de-de/library/windows/desktop/ms724451(v=vs.85).aspx
    ; With the release of Windows 8.1, the behavior of the GetVersionEx API has changed in the value it will return for the operating system version.
    ; The value returned by the GetVersionEx function now depends on how the application is manifested.

    ; If you don't want to depend on manifests and reply on this deprecated API, use kernel-mode RtlGetVersion:
    ; https://msdn.microsoft.com/en-us/library/windows/hardware/ff561910(v=vs.85).aspx

    Local Const $tOSVERSIONINFO = 'struct;dword OSVersionInfoSize;dword MajorVersion;dword MinorVersion;dword BuildNumber;dword PlatformId;wchar CSDVersion[128];endstruct'
    Local Const $tOSVERSIONINFOEX = $tOSVERSIONINFO & ';ushort ServicePackMajor;ushort ServicePackMinor;ushort SuiteMask;byte ProductType;byte Reserved'

    Local $tOSVI = DllStructCreate($tOSVERSIONINFOEX)
    DllStructSetData($tOSVI, 1, DllStructGetSize($tOSVI))
    Local $Ret = DllCall("ntdll.dll", "int", "RtlGetVersion", "ptr", DllStructGetPtr($tOSVI))
    If @error Or $Ret[0] <> 0 Then Return SetError(1, 0, 0) ; RtlGetVersion returns STATUS_SUCCESS = 0

    ConsoleWrite("MajorVersion=" & DllStructGetData($tOSVI,"MajorVersion") & @crlf)
    ConsoleWrite("MinorVersion=" & DllStructGetData($tOSVI,"MinorVersion") & @crlf)
    ConsoleWrite("ProductType=" & DllStructGetData($tOSVI,"ProductType") & @crlf)

    ; 0x0501 = Win XP
    ; 0x0502 = Win Server 2003
    ; 0x0600 = Win Vista
    ; 0x0601 = Win7 / Major Version = 6, Minor Version = 1
    ; 0x0602 = Win8
    ; 0x0603 = Win8.1
    ; 0x0604 = Win10 "Technical Preview"
    ; 0x0A00 = Win10 RTM (build 10240 or later) / Major Version = 10, Minor Version = 0

    ; Return "0x" & Hex(BitOR(BitShift(10, -8), 0), 4)
    Return "0x" & Hex(BitOR(BitShift(DllStructGetData($tOSVI, 2), -8), DllStructGetData($tOSVI, 3)), 4)
EndFunc   ;==>__WINVER_RtlGetVersion


Func __WINVER_GetVersionExW()
    Local $tOSVI = DllStructCreate('dword;dword;dword;dword;dword;wchar[128]')
    DllStructSetData($tOSVI, 1, DllStructGetSize($tOSVI))
    Local $Ret = DllCall('kernel32.dll', 'int', 'GetVersionExW', 'ptr', DllStructGetPtr($tOSVI))
    If (@error) Or (Not $Ret[0]) Then Return SetError(1, 0, 0)
    Return BitOR(BitShift(DllStructGetData($tOSVI, 2), -8), DllStructGetData($tOSVI, 3))
EndFunc   ;==>__WINVER_GetVersionExW

 

Edited by KaFu
Link to comment
Share on other sites

KaFu

Hello

Maybe replace

Before

Local Const $tOSVERSIONINFO = 'struct;dword OSVersionInfoSize;dword MajorVersion;dword MinorVersion;dword BuildNumber;dword PlatformId;wchar CSDVersion[128];endstruct'

After

Local Const $tOSVERSIONINFO = 'dword OSVersionInfoSize;dword MajorVersion;dword MinorVersion;dword BuildNumber;dword PlatformId;wchar CSDVersion[128]'

Changelog - deleted

struct;
;endstruct

 

Link to comment
Share on other sites

KaFu

Hello

If use thix fix - worked 100% on Windows 2000 and Windows 10

Please, write, how in your script use this function

OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION

OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION

GetSystemMetrics(SM_SERVERR2) != 0

OSVERSIONINFOEX.wSuiteMask & VER_SUITE_WH_SERVER

GetSystemMetrics(SM_SERVERR2) == 0

(OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION) && (SYSTEM_INFO.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)

It is need for identify what operating system because Version number may be identity 10.0 or 5.2 (for example)

Operating system Version number dwMajorVersion dwMinorVersion Other
Windows 10 10.0* 10 0 OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION
Windows Server 2016 10.0* 10 0 OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION
         
         
         
         
         
         
         
         
Windows Server 2003 R2 5.2 5 2 GetSystemMetrics(SM_SERVERR2) != 0
Windows Home Server 5.2 5 2 OSVERSIONINFOEX.wSuiteMask & VER_SUITE_WH_SERVER
Windows Server 2003 5.2 5 2 GetSystemMetrics(SM_SERVERR2) == 0
Windows XP Professional x64 Edition 5.2 5 2 (OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION) && (SYSTEM_INFO.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
         
         
 

 

Edited by SharkyEXE
Link to comment
Share on other sites

Try this:

ConsoleWrite((0x0A00 > 0x0601) & @CRLF)

Local $__WINVER_GetVersionExW = "0x" & Hex(__WINVER_GetVersionExW(), 4)
Local $__WINVER_RtlGetVersion = __WINVER_RtlGetVersion()

ConsoleWrite("$__WINVER_GetVersionExW" & @TAB & @TAB & $__WINVER_GetVersionExW & @CRLF)
ConsoleWrite("$__WINVER_RtlGetVersion" & @TAB & @TAB & $__WINVER_RtlGetVersion & @CRLF)

If $__WINVER_RtlGetVersion >= 0x0604 Then ; Current OS is "Win10 - Technical Preview" or up
    ConsoleWrite("+" & @TAB & $__WINVER_RtlGetVersion & @CRLF)
Else
    ConsoleWrite("-" & @TAB & $__WINVER_RtlGetVersion & @CRLF)
EndIf

Func __WINVER_RtlGetVersion()
    ; GetVersionEx
    ; https://msdn.microsoft.com/de-de/library/windows/desktop/ms724451(v=vs.85).aspx
    ; With the release of Windows 8.1, the behavior of the GetVersionEx API has changed in the value it will return for the operating system version.
    ; The value returned by the GetVersionEx function now depends on how the application is manifested.

    ; If you don't want to depend on manifests and reply on this deprecated API, use kernel-mode RtlGetVersion:
    ; https://msdn.microsoft.com/en-us/library/windows/hardware/ff561910(v=vs.85).aspx

    Local Const $tOSVERSIONINFO = 'dword OSVersionInfoSize;dword MajorVersion;dword MinorVersion;dword BuildNumber;dword PlatformId;wchar CSDVersion[128]'
    Local Const $tOSVERSIONINFOEX = $tOSVERSIONINFO & ';ushort ServicePackMajor;ushort ServicePackMinor;ushort SuiteMask;byte ProductType;byte Reserved'

    Local $tOSVI = DllStructCreate($tOSVERSIONINFOEX)
    DllStructSetData($tOSVI, 1, DllStructGetSize($tOSVI))
    Local $Ret = DllCall("ntdll.dll", "int", "RtlGetVersion", "ptr", DllStructGetPtr($tOSVI))
    If @error Or $Ret[0] <> 0 Then Return SetError(1, 0, 0) ; RtlGetVersion returns STATUS_SUCCESS = 0

    If BitAND(DllStructGetData($tOSVI, "MajorVersion"), 10) Then
        If BitAND(DllStructGetData($tOSVI, "ProductType"), 0x0000001) Then ; 0x0000001 = VER_NT_WORKSTATION
            ConsoleWrite("+ Windows 10" & @CRLF)
        Else
            ConsoleWrite("+ Windows Server 2016" & @CRLF)
        EndIf

    ElseIf BitAND(DllStructGetData($tOSVI, "MajorVersion"), 5) And BitAND(DllStructGetData($tOSVI, "MinorVersion"), 2) Then
        Local $aResult = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 89) ; 89 = SM_SERVERR2
        If @error Then Return SetError(@error, @extended, 0)
        If $aResult[0] Then
            ConsoleWrite("+ Windows Server 2003 R2" & @CRLF)
        Else
            If BitAND(DllStructGetData($tOSVI, "SuiteMask"), 0x00008000) Then ; 0x00008000 = VER_SUITE_WH_SERVER
                ConsoleWrite("+ Windows Home Server" & @CRLF)
            Else
                If BitAND(DllStructGetData($tOSVI, "ProductType"), 0x0000001) and StringRight(@OSArch, 2) = "64" Then ; 0x0000001 = VER_NT_WORKSTATION
                    ; @OSArch should deliver the same info as SYSTEM_INFO.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64
                    ConsoleWrite("+ Windows XP Professional x64 Edition" & @crlf)
                Else
                    ConsoleWrite("+ Windows Server 2003" & @crlf)

                endif
            EndIf
        EndIf
    Else
        ConsoleWrite("MajorVersion=" & DllStructGetData($tOSVI, "MajorVersion") & @CRLF)
        ConsoleWrite("MinorVersion=" & DllStructGetData($tOSVI, "MinorVersion") & @CRLF)
    EndIf


    Return "0x" & Hex(BitOR(BitShift(DllStructGetData($tOSVI, 2), -8), DllStructGetData($tOSVI, 3)), 4)
EndFunc   ;==>__WINVER_RtlGetVersion


Func __WINVER_GetVersionExW()
    Local $tOSVI = DllStructCreate('dword;dword;dword;dword;dword;wchar[128]')
    DllStructSetData($tOSVI, 1, DllStructGetSize($tOSVI))
    Local $Ret = DllCall('kernel32.dll', 'int', 'GetVersionExW', 'ptr', DllStructGetPtr($tOSVI))
    If (@error) Or (Not $Ret[0]) Then Return SetError(1, 0, 0)
    Return BitOR(BitShift(DllStructGetData($tOSVI, 2), -8), DllStructGetData($tOSVI, 3))
EndFunc   ;==>__WINVER_GetVersionExW

Edit: Removed "struct" keywords

Edited by KaFu
Link to comment
Share on other sites

KaFu

Hello

I use Autoit 3.3.6.1 and Microsoft Windows 7 Professional Service Pack 1 x64 Russian

I use your script this

After run your script this - write what my system Windows 10

Please, fix

When i use your script this on Microsoft Windows 7 Professional Service Pack 1 x64 Russian

Your script was return (stroke 58 and 59)

Quote

ConsoleWrite("MajorVersion=" & DllStructGetData($tOSVI, "MajorVersion") & @CRLF)
ConsoleWrite("MinorVersion=" & DllStructGetData($tOSVI, "MinorVersion") & @CRLF)

Thank You!

Снимок1.png

Link to comment
Share on other sites

Oh, looking at my old code, that couldn't work :), happy new year to everyone!

ConsoleWrite((0x0A00 > 0x0601) & @CRLF)

Local $__WINVER_GetVersionExW = "0x" & Hex(__WINVER_GetVersionExW(), 4)
Local $__WINVER_RtlGetVersion = __WINVER_RtlGetVersion()

ConsoleWrite("$__WINVER_GetVersionExW" & @TAB & @TAB & $__WINVER_GetVersionExW & @CRLF)
ConsoleWrite("$__WINVER_RtlGetVersion" & @TAB & @TAB & $__WINVER_RtlGetVersion & @CRLF)

If $__WINVER_RtlGetVersion >= 0x0604 Then ; Current OS is "Win10 - Technical Preview" or up
    ConsoleWrite("+" & @TAB & $__WINVER_RtlGetVersion & @CRLF)
Else
    ConsoleWrite("-" & @TAB & $__WINVER_RtlGetVersion & @CRLF)
EndIf

Func __WINVER_RtlGetVersion()
    ; GetVersionEx
    ; https://msdn.microsoft.com/de-de/library/windows/desktop/ms724451(v=vs.85).aspx
    ; With the release of Windows 8.1, the behavior of the GetVersionEx API has changed in the value it will return for the operating system version.
    ; The value returned by the GetVersionEx function now depends on how the application is manifested.

    ; If you don't want to depend on manifests and reply on this deprecated API, use kernel-mode RtlGetVersion:
    ; https://msdn.microsoft.com/en-us/library/windows/hardware/ff561910(v=vs.85).aspx

    Local Const $tOSVERSIONINFO = 'dword OSVersionInfoSize;dword MajorVersion;dword MinorVersion;dword BuildNumber;dword PlatformId;wchar CSDVersion[128]'
    Local Const $tOSVERSIONINFOEX = $tOSVERSIONINFO & ';ushort ServicePackMajor;ushort ServicePackMinor;ushort SuiteMask;byte ProductType;byte Reserved'

    Local $tOSVI = DllStructCreate($tOSVERSIONINFOEX)
    DllStructSetData($tOSVI, 1, DllStructGetSize($tOSVI))
    Local $Ret = DllCall("ntdll.dll", "int", "RtlGetVersion", "ptr", DllStructGetPtr($tOSVI))
    If @error Or $Ret[0] <> 0 Then Return SetError(1, 0, 0) ; RtlGetVersion returns STATUS_SUCCESS = 0

    ConsoleWrite("MajorVersion=" & DllStructGetData($tOSVI, "MajorVersion") & @CRLF)
    ConsoleWrite("MinorVersion=" & DllStructGetData($tOSVI, "MinorVersion") & @CRLF)
    ; https://docs.microsoft.com/ru-ru/windows/win32/api/winnt/ns-winnt-osversioninfoexa?redirectedfrom=MSDN
    Switch DllStructGetData($tOSVI, "MajorVersion")
        Case 10
            Switch DllStructGetData($tOSVI, "MinorVersion")
                Case 0
                    If BitAND(DllStructGetData($tOSVI, "ProductType"), 0x0000001) Then ; 0x0000001 = VER_NT_WORKSTATION
                        ConsoleWrite("+ Windows 10" & @CRLF)
                    Else
                        ConsoleWrite("+ Windows Server 2016" & @CRLF)
                    EndIf
                Case Else
                    ConsoleWrite("- No Windows Version determined" & @CRLF)
            EndSwitch
        Case 6
            Switch DllStructGetData($tOSVI, "MinorVersion")
                Case 0
                    If BitAND(DllStructGetData($tOSVI, "ProductType"), 0x0000001) Then ; 0x0000001 = VER_NT_WORKSTATION
                        ConsoleWrite("+ Windows Vista" & @CRLF)
                    Else
                        ConsoleWrite("+ Windows Server 2008" & @CRLF)
                    EndIf
                Case 1
                    If BitAND(DllStructGetData($tOSVI, "ProductType"), 0x0000001) Then ; 0x0000001 = VER_NT_WORKSTATION
                        ConsoleWrite("+ Windows 7" & @CRLF)
                    Else
                        ConsoleWrite("+ Windows Server 2008 R2" & @CRLF)
                    EndIf
                Case 2
                    If BitAND(DllStructGetData($tOSVI, "ProductType"), 0x0000001) Then ; 0x0000001 = VER_NT_WORKSTATION
                        ConsoleWrite("+ Windows 8" & @CRLF)
                    Else
                        ConsoleWrite("+ Windows Server 2012" & @CRLF)
                    EndIf
                Case 3
                    If BitAND(DllStructGetData($tOSVI, "ProductType"), 0x0000001) Then ; 0x0000001 = VER_NT_WORKSTATION
                        ConsoleWrite("+ Windows 8.1" & @CRLF)
                    Else
                        ConsoleWrite("+ Windows Server 2012 R2" & @CRLF)
                    EndIf
                Case Else
                    ConsoleWrite("- No Windows Version determined" & @CRLF)
            EndSwitch
        Case 5
            Switch DllStructGetData($tOSVI, "MinorVersion")
                Case 0
                    ConsoleWrite("+ Windows 2000" & @CRLF)
                Case 1
                    ConsoleWrite("+ Windows XP" & @CRLF)
                Case 2
                    Local $aResult = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 89) ; 89 = SM_SERVERR2
                    If @error Then Return SetError(@error, @extended, 0)
                    If $aResult[0] Then
                        ConsoleWrite("+ Windows Server 2003 R2" & @CRLF)
                    Else
                        If BitAND(DllStructGetData($tOSVI, "SuiteMask"), 0x00008000) Then ; 0x00008000 = VER_SUITE_WH_SERVER
                            ConsoleWrite("+ Windows Home Server" & @CRLF)
                        Else
                            If BitAND(DllStructGetData($tOSVI, "ProductType"), 0x0000001) And StringRight(@OSArch, 2) = "64" Then ; 0x0000001 = VER_NT_WORKSTATION
                                ; @OSArch should deliver the same info as SYSTEM_INFO.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64
                                ConsoleWrite("+ Windows XP Professional x64 Edition" & @CRLF)
                            Else
                                ConsoleWrite("+ Windows Server 2003" & @CRLF)
                            EndIf
                        EndIf
                    EndIf
                Case Else
                    ConsoleWrite("- No Windows Version determined" & @CRLF)
            EndSwitch
        Case Else
            ConsoleWrite("- No Windows Version determined" & @CRLF)
    EndSwitch

    Return "0x" & Hex(BitOR(BitShift(DllStructGetData($tOSVI, 2), -8), DllStructGetData($tOSVI, 3)), 4)
EndFunc   ;==>__WINVER_RtlGetVersion


Func __WINVER_GetVersionExW()
    Local $tOSVI = DllStructCreate('dword;dword;dword;dword;dword;wchar[128]')
    DllStructSetData($tOSVI, 1, DllStructGetSize($tOSVI))
    Local $Ret = DllCall('kernel32.dll', 'int', 'GetVersionExW', 'ptr', DllStructGetPtr($tOSVI))
    If (@error) Or (Not $Ret[0]) Then Return SetError(1, 0, 0)
    Return BitOR(BitShift(DllStructGetData($tOSVI, 2), -8), DllStructGetData($tOSVI, 3))
EndFunc   ;==>__WINVER_GetVersionExW

 

Link to comment
Share on other sites

Unfortunately the OSVersion info doesn't provide enough information especially when dealing with multiple build versions of Windows 10 in our environment, as some of our software doesn't work across all builds (usually because some features are only available on specific builds):

OS Versions: 7, 10, 2008 R2, 2012 R2, 2016, 2019
OS Editions: Home, Professional or Enterprise
OS Builds: 1709, 1803, 1809, 1903, 1909

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion can usually be used to determine most of this info, however WMI is generally more consistent when running across multiple OS versions.

Global $g_sOSCaption, $g_sOSVersion
_GetOSInfo()
ConsoleWrite("OS Caption : " & $g_sOSCaption & @CRLF & "OS Version : " & $g_sOSVersion & @CRLF)
Func _GetOSInfo()
    Local $oSystemSet = ObjGet("winmgmts:").InstancesOf ("Win32_OperatingSystem")
    If IsObj($oSystemSet) Then
        For $oSystem In $oSystemSet
            $g_sOSCaption = $oSystem.Caption
            $g_sOSVersion = $oSystem.Version
        Next
    EndIf
EndFunc

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...