Detecting windows 10 only

Hello,
I have a couple of win applications. Since they are freeware, I decided to support only Windows 10.
Can somebody supply me with the necessary code so that PCs running previous versions are alerted that the app won’t run on their machines?
Thank you.

If CWWindowsVersion() <> 10 then MsgBox "Only Windows 10 is supported" Quit End If

Function CWWindowsVersion() As double
//WindowsVersion by Christian Wheel - http://ChristianWheel.com
  dim s as new shell, res as string, lBracket as integer
  s.mode=0
  s.execute("ver")
  lBracket=instr(s.result, "[")
  if lBracket<1 then return 0 'Should never happen unless a newer version of Windows does something weird
  res=mid(s.Result, lbracket+1)
  res=replace(lowercase(res), "version ", "")
  return cdbl(res)
End Function

Maybe check SystemInformationMBS module if you use MBS Plugin.

Thank you, Christian.

@Christian Schmitz: I do not use MBS Plugins, but thank you for answering.

Be careful with localization.
In my computer there is no “version” but “Versin”

[quote=274850:@Ramon SASTRE]Be careful with localization.
In my computer there is no “version” but “Versión”[/quote]

Very good point!

Here’s a modified version that will be more tolerant of other locales. It still won’t work on systems that use other character sets for numeric values, however.

Function CWWindowsVersion() As Double //WindowsVersion by Christian Wheel - http://ChristianWheel.com dim s as new shell, res as string, lBracket as integer, words() as string, i as integer s.mode=0 s.execute("ver") lBracket=instr(s.result, "[") if lBracket<1 then return 0 res=mid(s.Result, lbracket+1) res=replaceall(res, "]", "") words()=split(res, " ") for i=0 to ubound(Words)-1 if IsNumeric(Words(i)) then Exit next i //res=replace(lowercase(res), "version ", "") return cdbl(Words(i)) End Function

Fine. Thank you.

Or just grab WFS and use the method in there (it might need an update)

Here’s the Microsoft recommended way, which avoids any string comparisons.

Attributes("StructureAlignment" = 0) Structure OSVERSIONINFOEX
  dwOSVersionInfoSize As Int32
  dwMajorVersion As Int32
  dwMinorVersion As Int32
  dwBuildNumber As Int32
  dwPlatformId As Int32
  szCSDVersion(127) As Int16 // Technicaly it's WCHAR[128]
  wServicePackMajor As Int16
  wServicePackMinor As Int16
  wSuiteMask As Int16
  wProductType As Int8
  wReserved As Int8
End Structure

Private Function IsWindows10OrGreater() As Boolean
  #If TargetWin32
    Declare Function VerSetConditionMask Lib "Kernel32.dll" ( dwlConditionMask As UInt64, dwTypeBitMask As Int32, dwConditionMask As Int8) As UInt64
    Declare Function VerifyVersionInfoW Lib "Kernel32.dll" (ByRef lpVersionInfo As OSVERSIONINFOEX, dwTypeMask As Int32, dwlConditionMask As Int64) As Boolean
    Const VER_MAJORVERSION = &h02
    Const VER_GREATER_EQUAL = 3
    
    Dim vers As OSVERSIONINFOEX
    vers.dwOSVersionInfoSize = OSVERSIONINFOEX.Size
    vers.dwMajorVersion = 10
    
    Dim mask As UInt64
    mask = VerSetConditionMask(mask, VER_MAJORVERSION, VER_GREATER_EQUAL)
    Return VerifyVersionInfoW(vers, VER_MAJORVERSION, mask)
  #Else
    Return False
  #EndIf
End Function

Joe, thank you. Very much appreciated.
But forgive my dumb question: how should I deal with the “structure” block? Are those items to be entered as properties?
Thanks again.

[quote=274908:@Carlo Rubini]Joe, thank you. Very much appreciated.
But forgive my dumb question: how should I deal with the “structure” block? Are those items to be entered as properties?
Thanks again.[/quote]

Copy the text starting at “Structure OSVERSIONINFOEX” through to “End Structure” and paste it into the IDE. Then add the “StructureAlignment” attribute in the attributes editor.

All right. Thank you.

Just FYI joes post above resulted in a bug being found <https://xojo.com/issue/44444>

That’s why he said to copy the text starting at “Structure OSVERSIONINFOEX”.

@Joe Ranieri : In your example there is:

Const VER_GREATER_EQUAL = 5

However, copy-and-pasted from here: VerSetConditionMask function

VER_EQUAL - 1 - The current value must be equal to the specified value. VER_GREATER - 2 - The current value must be greater than the specified value. VER_GREATER_EQUAL - 3 -The current value must be greater than or equal to the specified value. VER_LESS - 4 - The current value must be less than the specified value. VER_LESS_EQUAL - 5 The current value must be less than or equal to the specified value.

I may have copied this over from an older project that had a bug in it. I’ve fixed the example.

Perhaps not better than OSVERSIONINFOEX, but WMIC could also be used.

wmic os get version

Not the best solution but could always use CMD ver command

Here is a list of build numbers Build Numbers