Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

GetOSVersion()


  • Please log in to reply
11 replies to this topic
TheGood
  • Members
  • 589 posts
  • Last active: Mar 22 2014 03:22 PM
  • Joined: 30 Jul 2007
Download
Last updated: June 9th, 2010

Largely based on the code found here but I also had to make quite a bit of research for the older operating systems.

All parameters are optional. Returns the version number of the operating system in the format %MajorVersionNumber%.%MinorVersionNumber%

Possible values for Windows NT-based operating systems are:
Return value:   Possible OS:
    6.1             Windows 7, Windows Server 2008 R2
    6.0             Windows Vista, Windows Server 2008
    5.2             Windows XP Professional x64 Edition, Windows Server 2003 and its derivatives
    5.1             Windows XP
    5.0             Windows 2000
    4.0             Windows NT 4.0

Possible values for non-Windows NT-based operating systems are:
Return value:   Possible OS:
    4.90            Windows ME
    4.10            Windows 98
    4.0             Windows 95

Editions detected for Windows 6.0 and 6.1 :

Ultimate Edition
Professional
Home Premium Edition
Home Basic Edition
Enterprise Edition
Business Edition
Starter Edition
Cluster Server Edition
Datacenter Edition
Datacenter Edition (core installation)
Enterprise Edition
Enterprise Edition (core installation)
Enterprise Edition for Itanium-based Systems
Small Business Server
Small Business Server Premium Edition
Standard Edition
Standard Edition (core installation)
Web Server Edition

Editions detected for Windows 5.2:

Datacenter Edition for Itanium-based Systems
Enterprise Edition for Itanium-based Systems
Datacenter x64 Edition
Enterprise x64 Edition
Standard x64 Edition
Compute Cluster Edition
Datacenter Edition
Enterprise Edition
Web Edition
Standard Edition

Editions detected for Windows 5.1:

Home Edition
Professional
Tablet PC Edition
Media Center Edition
Started Edition

Editions detected for Windows 5.0:

Professional
Server
Datacenter Server
Advanced Server

Simple usage example:

If (GetOSVersion() < 6)
    MsgBox, You need at least Windows Vista to continue!

Usage example with all values:

iVersionNumber := GetOSVersion(sOSName, bIs64, iServicePack, bIsNT, iBuildNumber)
MsgBox, %   "Fully qualified name: " sOSName
        . "`nBuild number: " iBuildNumber
        . "`nOS Version: " iVersionNumber
        . "`nLatest service pack: " iServicePack
        . "`n64-bit OS: " (bIs64 ? "Yes" : "No")
        . "`nNT-based: " (bIsNT ? "Yes" : "No")

Outputs this (for me):

Posted Image

Alternative functions

If all you need is the return value of GetOSVersion() (i.e. the major.minor version number), you can use this function instead, which is supported since Windows NT 3.1 and Windows 95 (but notice that there's no way to know if the version number is that of an NT-based OS or not when the major version number is 4):

GetOSVersion() {
    Return ((r := DllCall("GetVersion") & 0xFFFF) & 0xFF) "." (r >> 8)
}

Here is a version which prepends the platform ID, so that you can easily differentiate between OSes across platforms (i.e. NT-based and non-NT-based):

/*! Possible return values
Return value:   Possible OS:
    2.6.1           Windows 7, Windows Server 2008 R2
    2.6.0           Windows Vista, Windows Server 2008
    2.5.2           Windows XP Professional x64 Edition, Windows Server 2003 and its derivatives
    2.5.1           Windows XP
    2.5.0           Windows 2000
    2.4.0           Windows NT 4.0
    1.4.90          Windows ME
    1.4.10          Windows 98
    1.4.0           Windows 95
*/
GetOSVersion() {
    VarSetCapacity(cOSVersionInfo, 148)
    NumPut(148, cOSVersionInfo, "int")
    DllCall("GetVersionEx", "uint", &cOSVersionInfo)
    iMajorVersion := NumGet(cOSVersionInfo,  4, "uint")
    iMinorVersion := NumGet(cOSVersionInfo,  8, "uint")
    iPlatformID   := NumGet(cOSVersionInfo, 16, "uint")
    Return iPlatformID "." iMajorVersion "." iMinorVersion
}


shajul
  • Members
  • 571 posts
  • Last active: Aug 01 2015 03:45 PM
  • Joined: 15 Sep 2006
My version, just for reference..
For AHK_L, both Unicode and Ansi. May not be needed in AHK_L v2 as mentioned by Lexikos.

; ref - http://msdn.microsoft.com/en-us/library/ms724833
; AHK_L Only

If ( OSVersion := GetOSVersionInfo() )
  MsgBox % "OS Version`t:`t" OSVersion.EasyVersion
       . "`nOS Service pack`t:`t" . OSVersion.ServicePackString
       . "`nIs Workstation`t:`t" (OSVersion.ProductType = 1 ? "Yes" : "No")
       
GetOSVersionInfo() {
  static Ver
  If !Ver
  {
    VarSetCapacity(OSVer, 284, 0)
    NumPut(284, OSVer, 0, "UInt")
    If !DllCall("GetVersionExW", "Ptr", &OSVer)
       return 0 ; GetSysErrorText(A_LastError)
    Ver := Object()
    Ver.MajorVersion      := NumGet(OSVer, 4, "UInt")
    Ver.MinorVersion      := NumGet(OSVer, 8, "UInt")
    Ver.BuildNumber       := NumGet(OSVer, 12, "UInt")
    Ver.PlatformId        := NumGet(OSVer, 16, "UInt")
    Ver.ServicePackString := StrGet(&OSVer+20, 128, "UTF-16")
    Ver.ServicePackMajor  := NumGet(OSVer, 276, "UShort")
    Ver.ServicePackMinor  := NumGet(OSVer, 278, "UShort")
    Ver.SuiteMask         := NumGet(OSVer, 280, "UShort")
    Ver.ProductType       := NumGet(OSVer, 282, "UChar")
    Ver.EasyVersion       := Ver.MajorVersion . "." . Ver.MinorVersion . "." . Ver.BuildNumber
  }
  return Ver
}
Outputs this on my system
OS Version	    :	6.1.7601
OS Service pack	:	Service Pack 1
Is Workstation	:	Yes

Edit: Modified according to Lexikos's suggestions below!
If i've seen further it is by standing on the shoulders of giants

my site | ~shajul | WYSIWYG BBCode Editor

Deo
  • Members
  • 199 posts
  • Last active: Jan 31 2014 03:19 PM
  • Joined: 16 May 2010
very nice
does it work with ahk_L x32/x64?
I didn't see any "Ptr"s there so i guess it not support x64 build at least

shajul
  • Members
  • 571 posts
  • Last active: Aug 01 2015 03:45 PM
  • Joined: 15 Sep 2006
I have used "UPtr" with an idea that it will support x64. It should work, not tested though.
If i've seen further it is by standing on the shoulders of giants

my site | ~shajul | WYSIWYG BBCode Editor

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
You can simplify by using the "W" version for both builds; i.e. call GetVersionExW and add "UTF-16" as the third parameter to StrGet. However, please note that StrGet's Length parameter is "the maximum number of characters to read", so it should be the same in both ANSI and Unicode versions. In this case you can just omit it since the string is always null-terminated.

AutoHotkey doesn't support unsigned 64-bit integers, so "UPtr" is only unsigned on 32-bit builds. It doesn't help readability either, so I'd just use "Ptr". (FYI: For any integer type, NumPut and DllCall args without the "*" or "P" suffix behave exactly the same with or without the "U" prefix.)

Your script does work in (v2) 64-bit; however, the first field is only a DWORD (UInt), not UPtr. If you were to make this mistake somewhere else, you might overwrite some important data (in the second DWORD field), but in this case it doesn't matter.
NumPut(284, OSVer, "UInt")  ; It's a DWORD, always 32-bit.
    If !DllCall("GetVersionExW", "Ptr", &OSVer)  ; Always call Unicode version.
    ...
    Ver.ServicePackString := StrGet(&OSVer+20, 128, "UTF-16") ; or:
    Ver.ServicePackString := StrGet(&OSVer+20, "UTF-16")

May not be needed in AHK_L v2

A_OSVersion will probably be the same as GetOSVersionInfo().EasyVersion. It won't include any other information.

shajul
  • Members
  • 571 posts
  • Last active: Aug 01 2015 03:45 PM
  • Joined: 15 Sep 2006
@Lexikos: Thanks a lot for your reply. Your reply always is a learning experience. Posted Image
I have made the changes and updated the post.

however, the first field is only a DWORD (UInt), not UPtr

So stupid of me.
If i've seen further it is by standing on the shoulders of giants

my site | ~shajul | WYSIWYG BBCode Editor

sabot7726
  • Members
  • 69 posts
  • Last active: Aug 12 2013 03:29 AM
  • Joined: 27 Nov 2006
Hmm I'm trying to use this script to get some info that is then presented in a GUI but so far it's treating my OSVersion.ServicePackString as just text instead of displaying its value.

How do I put this output in a gui?

shajul
  • Members
  • 571 posts
  • Last active: Aug 01 2015 03:45 PM
  • Joined: 15 Sep 2006

OSVersion.ServicePackString as just text instead of displaying its value.

How do I put this output in a gui?


I guess this is what you want
Gui, Add, Text, x5 y5,% "OS Service pack`t:`t" . OSVersion.ServicePackString
Gui, Show, Autosize

If i've seen further it is by standing on the shoulders of giants

my site | ~shajul | WYSIWYG BBCode Editor

sabot7726
  • Members
  • 69 posts
  • Last active: Aug 12 2013 03:29 AM
  • Joined: 27 Nov 2006
Cool thanks I'll give it a shot when I get time :)

aaronbewza
  • Members
  • 466 posts
  • Last active: Feb 05 2013 08:40 AM
  • Joined: 20 Feb 2011
I am interested in this script for its ability to detect 32 or 64-bit systems. At the moment my own script looks for "Program Files (x86)" folder to determine if the system is 32 or 64-bit. If the folder exists, then the system is obviously 64-bit. I don't like this method and would rather use your method! But I'm stuck. I tried this (from your code) but it reports "32-bit" on both 32 and 64-bit Windows:
GetOSVersion() {
    Return ((r := DllCall("GetVersion") & 0xFFFF) & 0xFF) "." (r >> 8)
}

MsgBox, % (bIs64 ? "64-bit" : "32-bit")" System Detected"

...and I have no idea what I'm doing. Can you help me get this one function working?
This is the code I use now (which I'd rather not use):
; Checks if system is x86 or x64

IfExist, %SystemDrive%\Program Files (x86) ; If this folder exists system is 64bit
GoTo 64bit ; Directs script past reporting 32bit system information

IfNotExist, %SystemDrive%\Program Files (x86) ; If this folder does not exist system is 32bit or other
GoTo 32bit

32bit:
Gui, Add, Text, x27 y60 w360 h30 +Center, 32-bit System Detected
GoTo WindowRemaining

64bit:
Gui, Add, Text, x27 y60 w360 h30 +Center, 64-bit System Detected
GoTo WindowRemaining ; Not necessary but keeps continuity

WindowRemaining:
(rest of the window is built here)

The method I use has a chance that some future version of Windows will make the "Program Files (x86)" folder obsolete, and if that happens, my script will not be usable.
I would like to use something like:
Gui, Add, Text, x27 y60 w360 h30 +Center, (*get info if 32 or 64-bit*) System Detected
Thanks in advance for any information you can give me :)
Aaron

shajul
  • Members
  • 571 posts
  • Last active: Aug 01 2015 03:45 PM
  • Joined: 15 Sep 2006
use SYSTEM_INFO structure to get processor architecture
ref: http://msdn.microsof...ibrary/ms724958[/url]
If i've seen further it is by standing on the shoulders of giants

my site | ~shajul | WYSIWYG BBCode Editor

aaronbewza
  • Members
  • 466 posts
  • Last active: Feb 05 2013 08:40 AM
  • Joined: 20 Feb 2011
Thank you Shajul... more reading for me to do :) I realized what I was asking was not directly related to this thread, so I posted my question in a new Help Request which has since been answered. I am still going to use this script to retrieve other system info, it's awesome! Thanks again.