6

We've got a script that uses the platform module to detect OS version of our various clients.

Looking through the source for platform.py, I can see that on Windows systems, it's using sys.getwindowsverion(). Unfortunately, on Windows 8.1 systems, that particular function reports:

>>> sys.getwindowsversion()
sys.getwindowsversion(major=6, minor=2, build=9200, platform=2, service_pack='')

Windows 8.1 is 6.3.9600:

Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.

C:\Windows\system32>ver

Microsoft Windows [Version 6.3.9600]

So, I realize I could write some extra logic around my call to platform.release(), and if that returns 8, do a secondary check and try to run ver, but that seems slightly convoluted.

Does anyone know of a better way?

Running ActivePython 2.7.2.5 in case that matters . . .

ernie
  • 6,356
  • 23
  • 28
  • Windows can lie to you, if it decides you should be running in win8 mode. This might be the case for win8 apps in modern that haven't been updated to 8.1, but I doubt you are running python in modern. – ohmusama Oct 02 '13 at 00:39
  • Oh, fudge. Python uses the [MS `GetVersionEx()` function](http://msdn.microsoft.com/en-us/library/windows/desktop/ms724451(v=vs.85).aspx) for this. Follow the link: looks they're replacing it with an unusable mess of new functions :-( – Tim Peters Oct 02 '13 at 00:45
  • 3
    FYI, I [opened a bug report about this](http://bugs.python.org/issue19143) on the Python bug tracker. In the meantime, do anything that works ;-) – Tim Peters Oct 02 '13 at 00:52
  • @TimPeters Thanks for the legwork. I'd heard grumblings from some of the Windows developers at work about the GetVersionEx() changes, but wasn't sure if that was related or not . . . – ernie Oct 02 '13 at 14:17

2 Answers2

4

Microsoft changed the way that the version function behave. See this page for some more information.

The way that I worked around the problem is to use ctypes and a kernel mode function, RtlGetVersion. Despite this being a kernel mode function it can be called from user mode just fine. I've tried this on many versions of Windows and not had an issue.

import ctypes

class OSVERSIONINFOEXW(ctypes.Structure):
    _fields_ = [('dwOSVersionInfoSize', ctypes.c_ulong),
                ('dwMajorVersion', ctypes.c_ulong),
                ('dwMinorVersion', ctypes.c_ulong),
                ('dwBuildNumber', ctypes.c_ulong),
                ('dwPlatformId', ctypes.c_ulong),
                ('szCSDVersion', ctypes.c_wchar*128),
                ('wServicePackMajor', ctypes.c_ushort),
                ('wServicePackMinor', ctypes.c_ushort),
                ('wSuiteMask', ctypes.c_ushort),
                ('wProductType', ctypes.c_byte),
                ('wReserved', ctypes.c_byte)]

def get_os_version():
    """
    Get's the OS major and minor versions.  Returns a tuple of
    (OS_MAJOR, OS_MINOR).
    """
    os_version = OSVERSIONINFOEXW()
    os_version.dwOSVersionInfoSize = ctypes.sizeof(os_version)
    retcode = ctypes.windll.Ntdll.RtlGetVersion(ctypes.byref(os_version))
    if retcode != 0:
        raise Exception("Failed to get OS version")

    return os_version.dwMajorVersion, os_version.dwMinorVersion
Isaac
  • 215
  • 2
  • 8
1

You can simple get it from registry HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion there you have value name CurrentVersion And the Data in Windows 8.1 will be 6.3 It will work an any windows platform