11# A part of NonVisual Desktop Access (NVDA)
2- # Copyright (C) 2006-2020 NV Access Limited
2+ # Copyright (C) 2006-2020 NV Access Limited, Bill Dengler, Joseph Lee
33# This file is covered by the GNU General Public License.
44# See the file COPYING for more details.
55
66import sys
77import os
8+ import functools
89import winUser
910
1011winVersion = sys .getwindowsversion ()
1516 winVersionText += ".%d" % winVersion .service_pack_minor
1617winVersionText += " %s" % ("workstation" ,"domain controller" ,"server" )[winVersion .product_type - 1 ]
1718
19+
20+ @functools .total_ordering
21+ class WinVersion (object ):
22+ """
23+ Represents a Windows release.
24+ Includes version major, minor, build, service pack information,
25+ as well as tools such as checking for specific Windows 10 releases.
26+ """
27+
28+ def __init__ (
29+ self ,
30+ release : str = None ,
31+ major : int = 0 ,
32+ minor : int = 0 ,
33+ build : int = 0 ,
34+ servicePack : str = ""
35+ ):
36+ if release in (None , "" ):
37+ self .major = major
38+ self .minor = minor
39+ self .build = build
40+ elif release == "7" :
41+ self .major = 6
42+ self .minor = 1
43+ self .build = 7601
44+ elif release == "8" :
45+ self .major = 6
46+ self .minor = 2
47+ self .build = 9200
48+ elif release == "8.1" :
49+ self .major = 6
50+ self .minor = 3
51+ self .build = 9600
52+ elif release in ("10" , "1507" ):
53+ self .major = 10
54+ self .minor = 0
55+ self .build = 10240
56+ elif release in WIN10_VERSIONS_TO_BUILDS :
57+ self .major = 10
58+ self .minor = 0
59+ self .build = WIN10_VERSIONS_TO_BUILDS [release ]
60+ else :
61+ raise ValueError ("Cannot create Windows version information for the specified release" )
62+ self .servicePack = "1" if release == "7" else ""
63+
64+ def __eq__ (self , other ):
65+ return (
66+ (self .major , self .minor , self .build )
67+ == (other .major , other .minor , other .build )
68+ )
69+
70+ def __ge__ (self , other ):
71+ return (
72+ (self .major , self .minor , self .build )
73+ >= (other .major , other .minor , other .build )
74+ )
75+
76+ def isWin10 (self , release : str = "1507" , atLeast : bool = True ):
77+ """
78+ Returns True if NVDA is running on the supplied release version of Windows 10.
79+ If no argument is supplied, returns True for all public Windows 10 releases.
80+ @param release: a release version of Windows 10 (such as 1903).
81+ @param atLeast: return True if NVDA is running on at least this Windows 10 build
82+ (i.e. this version or higher).
83+ """
84+ if self .major != 10 :
85+ return False
86+ # #11795: special cases.
87+ # Remove this workaround in a future API compatibility (year.1) release.
88+ # October 2020 Update is 20H2, not 2009.
89+ if release == "2009" :
90+ release = "20H2"
91+ if release not in WIN10_VERSIONS_TO_BUILDS :
92+ raise ValueError (f"Unknown Windows 10 release { release } " )
93+ if atLeast :
94+ return self .build >= WIN10_VERSIONS_TO_BUILDS [release ]
95+ else :
96+ return self .build > WIN10_VERSIONS_TO_BUILDS [release ]
97+
98+
99+ def getWinVer ():
100+ return WinVersion (
101+ major = winVersion .major ,
102+ minor = winVersion .minor ,
103+ build = winVersion .build ,
104+ servicePack = winVersion .service_pack
105+ )
106+
107+
108+ def getWinVerFromVersionText (versionText : str ):
109+ major , minor , build = versionText .split ("." )
110+ return WinVersion (
111+ major = int (major ),
112+ minor = int (minor ),
113+ build = int (build )
114+ )
115+
18116def isSupportedOS ():
19117 # NVDA can only run on Windows 7 Service pack 1 and above
20118 return (winVersion .major ,winVersion .minor ,winVersion .service_pack_major ) >= (6 ,1 ,1 )
@@ -28,38 +126,28 @@ def isUwpOcrAvailable():
28126
29127
30128WIN10_VERSIONS_TO_BUILDS = {
31- 1507 : 10240 ,
32- 1511 : 10586 ,
33- 1607 : 14393 ,
34- 1703 : 15063 ,
35- 1709 : 16299 ,
36- 1803 : 17134 ,
37- 1809 : 17763 ,
38- 1903 : 18362 ,
39- 1909 : 18363 ,
40- 2004 : 19041 ,
41- 2009 : 19042 ,
129+ " 1507" : 10240 ,
130+ " 1511" : 10586 ,
131+ " 1607" : 14393 ,
132+ " 1703" : 15063 ,
133+ " 1709" : 16299 ,
134+ " 1803" : 17134 ,
135+ " 1809" : 17763 ,
136+ " 1903" : 18362 ,
137+ " 1909" : 18363 ,
138+ " 2004" : 19041 ,
139+ "20H2" : 19042 ,
42140}
43141
44142
45143def isWin10 (version : int = 1507 , atLeast : bool = True ):
46144 """
145+ @deprecated: use getWinVer().isWin10 instead.
47146 Returns True if NVDA is running on the supplied release version of Windows 10. If no argument is supplied, returns True for all public Windows 10 releases.
48147 @param version: a release version of Windows 10 (such as 1903).
49148 @param atLeast: return True if NVDA is running on at least this Windows 10 build (i.e. this version or higher).
50149 """
51- if winVersion .major != 10 :
52- return False
53- try :
54- if atLeast :
55- return winVersion .build >= WIN10_VERSIONS_TO_BUILDS [version ]
56- else :
57- return winVersion .build == WIN10_VERSIONS_TO_BUILDS [version ]
58- except KeyError :
59- from logHandler import log
60- log .error ("Unknown Windows 10 version {}" .format (version ))
61- return False
62-
150+ return getWinVer ().isWin10 (release = str (version ), atLeast = atLeast )
63151
64152def isFullScreenMagnificationAvailable ():
65153 return (winVersion .major , winVersion .minor ) >= (6 , 2 )
0 commit comments