We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
WinVersion: add machine architecture property
Hi,

Stemming from #14397:

### Background:
Over the years, Windows supported various processor architectures from various vendors, including Intel x86 (32-bit), AMD64, Itanium (now discontinued), and ARM family (32-bit and 64-bit). While the base machine architecture for NVDA is x86, it provides support for x64 (Intel and AMD) and ARM64 through remote helper libraries.

While #14397 highlighted the need to improve support for ARM64 machines, it brought up an unspoken questino: can NVDA effectively detect different machine architectures? Moreover, thinking about this issue led me to believe that it would be helpful to let NVDA report machine architecture as part of Windows version information, similar to what Resource Monitor add-on provides.

### Is your feature request related to a problem? Please describe.
At the moment NVDA does recognize workstation versus server Windows releases, but not machine architecture, which could have helped debug #14397 and similar issues.

### Describe the solution you'd like
Add machine architecture (WinVersion.architecture) property to WinVersion class and report it at startup. This allows developers to figure out if the issue is specific to an architecture such as AMD64 or AM64, as well as detect test machines easily once ARM machines are used more on the cloud (currently virtual machines on the cloud are powered by x64 processors).

In addition, the following changes can be made:

1. App modules: 64-bit process dtection becoes easier thanks to checking for Windows machine architecture check.
2. Update check: made simpler by fetching WinVersion property.

### Describe alternatives you've considered
Leave code as is and rely on environment variables to detect machine architecture.

### Additional context
For an example, see josephsl/resourcemonitor, specifically Windows version script (NVDA+Shift+number row 6).

### Proposed solution:
Bring machine architecture detection code from Resource Monitor add-on to NVDA Core, likely to target 2023.1 or 2023.2. I'd be happy to mentor someone to bring this feature request to life.

Thanks.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `source/winVersion.py`
Content:
```
1 # A part of NonVisual Desktop Access (NVDA)
2 # Copyright (C) 2006-2022 NV Access Limited, Bill Dengler, Joseph Lee
3 # This file is covered by the GNU General Public License.
4 # See the file COPYING for more details.
5 
6 """A module used to record Windows versions.
7 It is also used to define feature checks such as
8 making sure NVDA can run on a minimum supported version of Windows.
9 
10 When working on this file, consider moving to winAPI.
11 """
12 
13 from typing import Optional
14 import sys
15 import os
16 import functools
17 import winreg
18 
19 
20 # Records a mapping between Windows builds and release names.
21 # These include build 10240 for Windows 10 1507 and releases with multiple release builds.
22 # These are applicable to Windows 10 and later as they report the same system version (10.0).
23 _BUILDS_TO_RELEASE_NAMES = {
24 	10240: "Windows 10 1507",
25 	10586: "Windows 10 1511",
26 	14393: "Windows 10 1607",
27 	15063: "Windows 10 1703",
28 	16299: "Windows 10 1709",
29 	17134: "Windows 10 1803",
30 	17763: "Windows 10 1809",
31 	18362: "Windows 10 1903",
32 	18363: "Windows 10 1909",
33 	19041: "Windows 10 2004",
34 	19042: "Windows 10 20H2",
35 	19043: "Windows 10 21H1",
36 	19044: "Windows 10 21H2",
37 	19045: "Windows 10 22H2",
38 	20348: "Windows Server 2022",
39 	22000: "Windows 11 21H2",
40 	22621: "Windows 11 22H2",
41 }
42 
43 
44 @functools.lru_cache(maxsize=1)
45 def _getRunningVersionNameFromWinReg() -> str:
46 	"""Returns the Windows release name defined in Windows Registry.
47 	This is applicable on Windows 10 Version 1511 (build 10586) and later.
48 	"""
49 	# Cache the version in use on the system.
50 	with winreg.OpenKey(
51 		winreg.HKEY_LOCAL_MACHINE, r"Software\Microsoft\Windows NT\CurrentVersion"
52 	) as currentVersion:
53 		# Version 20H2 and later where a separate display version string is used.
54 		try:
55 			releaseId = winreg.QueryValueEx(currentVersion, "DisplayVersion")[0]
56 		except OSError:
57 			# Don't set anything if this is Windows 10 1507 or earlier.
58 			try:
59 				releaseId = winreg.QueryValueEx(currentVersion, "ReleaseID")[0]
60 			except OSError:
61 				raise RuntimeError(
62 					"Release name is not recorded in Windows Registry on this version of Windows"
63 				) from None
64 	return releaseId
65 
66 
67 @functools.total_ordering
68 class WinVersion(object):
69 	"""
70 	Represents a Windows release.
71 	Includes version major, minor, build, service pack information,
72 	as well as tools such as checking for specific Windows 10 releases.
73 	"""
74 
75 	def __init__(
76 			self,
77 			major: int = 0,
78 			minor: int = 0,
79 			build: int = 0,
80 			releaseName: Optional[str] = None,
81 			servicePack: str = "",
82 			productType: str = ""
83 	):
84 		self.major = major
85 		self.minor = minor
86 		self.build = build
87 		if releaseName:
88 			self.releaseName = releaseName
89 		else:
90 			self.releaseName = self._getWindowsReleaseName()
91 		self.servicePack = servicePack
92 		self.productType = productType
93 
94 	def _getWindowsReleaseName(self) -> str:
95 		"""Returns the public release name for a given Windows release based on major, minor, and build.
96 		This is useful if release names are not defined when constructing this class.
97 		For example, 6.1 will return 'Windows 7'.
98 		For Windows 10, feature update release name will be included.
99 		On server systems, unless noted otherwise, client release names will be returned.
100 		For example, 'Windows 10 1809' will be returned on Server 2019 systems.
101 		"""
102 		if (self.major, self.minor) == (6, 1):
103 			return "Windows 7"
104 		elif (self.major, self.minor) == (6, 2):
105 			return "Windows 8"
106 		elif (self.major, self.minor) == (6, 3):
107 			return "Windows 8.1"
108 		elif self.major == 10:
109 			# From Version 1511 (build 10586), release Id/display version comes from Windows Registry.
110 			# However there are builds with no release name (Version 1507/10240)
111 			# or releases with different builds.
112 			# Look these up first before asking Windows Registry.
113 			if self.build in _BUILDS_TO_RELEASE_NAMES:
114 				return _BUILDS_TO_RELEASE_NAMES[self.build]
115 			return "Windows 10 unknown"
116 		else:
117 			return "Windows release unknown"
118 
119 	def __repr__(self):
120 		winVersionText = [self.releaseName]
121 		winVersionText.append(f"({self.major}.{self.minor}.{self.build})")
122 		if self.servicePack != "":
123 			winVersionText.append(f"service pack {self.servicePack}")
124 		if self.productType != "":
125 			winVersionText.append(self.productType)
126 		return " ".join(winVersionText)
127 
128 	def __eq__(self, other):
129 		return (
130 			(self.major, self.minor, self.build)
131 			== (other.major, other.minor, other.build)
132 		)
133 
134 	def __ge__(self, other):
135 		return (
136 			(self.major, self.minor, self.build)
137 			>= (other.major, other.minor, other.build)
138 		)
139 
140 
141 # Windows releases to WinVersion instances for easing comparisons.
142 WIN7 = WinVersion(major=6, minor=1, build=7600)
143 WIN7_SP1 = WinVersion(major=6, minor=1, build=7601, servicePack="1")
144 WIN8 = WinVersion(major=6, minor=2, build=9200)
145 WIN81 = WinVersion(major=6, minor=3, build=9600)
146 WIN10 = WIN10_1507 = WinVersion(major=10, minor=0, build=10240)
147 WIN10_1511 = WinVersion(major=10, minor=0, build=10586)
148 WIN10_1607 = WinVersion(major=10, minor=0, build=14393)
149 WIN10_1703 = WinVersion(major=10, minor=0, build=15063)
150 WIN10_1709 = WinVersion(major=10, minor=0, build=16299)
151 WIN10_1803 = WinVersion(major=10, minor=0, build=17134)
152 WIN10_1809 = WinVersion(major=10, minor=0, build=17763)
153 WIN10_1903 = WinVersion(major=10, minor=0, build=18362)
154 WIN10_1909 = WinVersion(major=10, minor=0, build=18363)
155 WIN10_2004 = WinVersion(major=10, minor=0, build=19041)
156 WIN10_20H2 = WinVersion(major=10, minor=0, build=19042)
157 WIN10_21H1 = WinVersion(major=10, minor=0, build=19043)
158 WIN10_21H2 = WinVersion(major=10, minor=0, build=19044)
159 WIN10_22H2 = WinVersion(major=10, minor=0, build=19045)
160 WINSERVER_2022 = WinVersion(major=10, minor=0, build=20348)
161 WIN11 = WIN11_21H2 = WinVersion(major=10, minor=0, build=22000)
162 WIN11_22H2 = WinVersion(major=10, minor=0, build=22621)
163 
164 
165 @functools.lru_cache(maxsize=1)
166 def getWinVer():
167 	"""Returns a record of current Windows version NVDA is running on.
168 	"""
169 	winVer = sys.getwindowsversion()
170 	# #12509: on Windows 10, fetch whatever Windows Registry says for the current build.
171 	# #12626: note that not all Windows 10 releases are labeled "Windows 10"
172 	# (build 22000 is Windows 11 despite major.minor being 10.0).
173 	try:
174 		if WinVersion(
175 			major=winVer.major,
176 			minor=winVer.minor,
177 			build=winVer.build
178 		) >= WIN11:
179 			releaseName = f"Windows 11 {_getRunningVersionNameFromWinReg()}"
180 		else:
181 			releaseName = f"Windows 10 {_getRunningVersionNameFromWinReg()}"
182 	except RuntimeError:
183 		releaseName = None
184 	return WinVersion(
185 		major=winVer.major,
186 		minor=winVer.minor,
187 		build=winVer.build,
188 		releaseName=releaseName,
189 		servicePack=winVer.service_pack,
190 		productType=("workstation", "domain controller", "server")[winVer.product_type - 1]
191 	)
192 
193 
194 def isSupportedOS():
195 	# NVDA can only run on Windows 7 Service pack 1 and above
196 	return getWinVer() >= WIN7_SP1
197 
198 
199 UWP_OCR_DATA_PATH = os.path.expandvars(r"$windir\OCR")
200 
201 
202 def isUwpOcrAvailable():
203 	return os.path.isdir(UWP_OCR_DATA_PATH)
204 
205 
206 def isFullScreenMagnificationAvailable() -> bool:
207 	"""
208 	Technically this is always False. The Magnification API has been marked by MS as unsupported for
209 	WOW64 applications such as NVDA. For our usages, support has been added since Windows 8, relying on our
210 	testing our specific usage of the API with each Windows version since Windows 8
211 	"""
212 	return getWinVer() >= WIN8
213
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/source/winVersion.py b/source/winVersion.py
--- a/source/winVersion.py
+++ b/source/winVersion.py
@@ -15,6 +15,7 @@
 import os
 import functools
 import winreg
+import platform
 
 
 # Records a mapping between Windows builds and release names.
@@ -68,7 +69,7 @@
 class WinVersion(object):
 	"""
 	Represents a Windows release.
-	Includes version major, minor, build, service pack information,
+	Includes version major, minor, build, service pack information, machine architecture,
 	as well as tools such as checking for specific Windows 10 releases.
 	"""
 
@@ -79,7 +80,8 @@
 			build: int = 0,
 			releaseName: Optional[str] = None,
 			servicePack: str = "",
-			productType: str = ""
+			productType: str = "",
+			processorArchitecture: str = ""
 	):
 		self.major = major
 		self.minor = minor
@@ -90,6 +92,7 @@
 			self.releaseName = self._getWindowsReleaseName()
 		self.servicePack = servicePack
 		self.productType = productType
+		self.processorArchitecture = processorArchitecture
 
 	def _getWindowsReleaseName(self) -> str:
 		"""Returns the public release name for a given Windows release based on major, minor, and build.
@@ -123,6 +126,8 @@
 			winVersionText.append(f"service pack {self.servicePack}")
 		if self.productType != "":
 			winVersionText.append(self.productType)
+		if self.processorArchitecture != "":
+			winVersionText.append(self.processorArchitecture)
 		return " ".join(winVersionText)
 
 	def __eq__(self, other):
@@ -187,7 +192,8 @@
 		build=winVer.build,
 		releaseName=releaseName,
 		servicePack=winVer.service_pack,
-		productType=("workstation", "domain controller", "server")[winVer.product_type - 1]
+		productType=("workstation", "domain controller", "server")[winVer.product_type - 1],
+		processorArchitecture=platform.machine()
 	)

{"golden_diff": "diff --git a/source/winVersion.py b/source/winVersion.py\n--- a/source/winVersion.py\n+++ b/source/winVersion.py\n@@ -15,6 +15,7 @@\n import os\r\n import functools\r\n import winreg\r\n+import platform\r\n \r\n \r\n # Records a mapping between Windows builds and release names.\r\n@@ -68,7 +69,7 @@\n class WinVersion(object):\r\n \t\"\"\"\r\n \tRepresents a Windows release.\r\n-\tIncludes version major, minor, build, service pack information,\r\n+\tIncludes version major, minor, build, service pack information, machine architecture,\r\n \tas well as tools such as checking for specific Windows 10 releases.\r\n \t\"\"\"\r\n \r\n@@ -79,7 +80,8 @@\n \t\t\tbuild: int = 0,\r\n \t\t\treleaseName: Optional[str] = None,\r\n \t\t\tservicePack: str = \"\",\r\n-\t\t\tproductType: str = \"\"\r\n+\t\t\tproductType: str = \"\",\r\n+\t\t\tprocessorArchitecture: str = \"\"\r\n \t):\r\n \t\tself.major = major\r\n \t\tself.minor = minor\r\n@@ -90,6 +92,7 @@\n \t\t\tself.releaseName = self._getWindowsReleaseName()\r\n \t\tself.servicePack = servicePack\r\n \t\tself.productType = productType\r\n+\t\tself.processorArchitecture = processorArchitecture\r\n \r\n \tdef _getWindowsReleaseName(self) -> str:\r\n \t\t\"\"\"Returns the public release name for a given Windows release based on major, minor, and build.\r\n@@ -123,6 +126,8 @@\n \t\t\twinVersionText.append(f\"service pack {self.servicePack}\")\r\n \t\tif self.productType != \"\":\r\n \t\t\twinVersionText.append(self.productType)\r\n+\t\tif self.processorArchitecture != \"\":\r\n+\t\t\twinVersionText.append(self.processorArchitecture)\r\n \t\treturn \" \".join(winVersionText)\r\n \r\n \tdef __eq__(self, other):\r\n@@ -187,7 +192,8 @@\n \t\tbuild=winVer.build,\r\n \t\treleaseName=releaseName,\r\n \t\tservicePack=winVer.service_pack,\r\n-\t\tproductType=(\"workstation\", \"domain controller\", \"server\")[winVer.product_type - 1]\r\n+\t\tproductType=(\"workstation\", \"domain controller\", \"server\")[winVer.product_type - 1],\r\n+\t\tprocessorArchitecture=platform.machine()\r\n \t)\n", "issue": "WinVersion: add machine architecture property\nHi,\r\n\r\nStemming from #14397:\r\n\r\n### Background:\r\nOver the years, Windows supported various processor architectures from various vendors, including Intel x86 (32-bit), AMD64, Itanium (now discontinued), and ARM family (32-bit and 64-bit). While the base machine architecture for NVDA is x86, it provides support for x64 (Intel and AMD) and ARM64 through remote helper libraries.\r\n\r\nWhile #14397 highlighted the need to improve support for ARM64 machines, it brought up an unspoken questino: can NVDA effectively detect different machine architectures? Moreover, thinking about this issue led me to believe that it would be helpful to let NVDA report machine architecture as part of Windows version information, similar to what Resource Monitor add-on provides.\r\n\r\n### Is your feature request related to a problem? Please describe.\r\nAt the moment NVDA does recognize workstation versus server Windows releases, but not machine architecture, which could have helped debug #14397 and similar issues.\r\n\r\n### Describe the solution you'd like\r\nAdd machine architecture (WinVersion.architecture) property to WinVersion class and report it at startup. This allows developers to figure out if the issue is specific to an architecture such as AMD64 or AM64, as well as detect test machines easily once ARM machines are used more on the cloud (currently virtual machines on the cloud are powered by x64 processors).\r\n\r\nIn addition, the following changes can be made:\r\n\r\n1. App modules: 64-bit process dtection becoes easier thanks to checking for Windows machine architecture check.\r\n2. Update check: made simpler by fetching WinVersion property.\r\n\r\n### Describe alternatives you've considered\r\nLeave code as is and rely on environment variables to detect machine architecture.\r\n\r\n### Additional context\r\nFor an example, see josephsl/resourcemonitor, specifically Windows version script (NVDA+Shift+number row 6).\r\n\r\n### Proposed solution:\r\nBring machine architecture detection code from Resource Monitor add-on to NVDA Core, likely to target 2023.1 or 2023.2. I'd be happy to mentor someone to bring this feature request to life.\r\n\r\nThanks.\n", "before_files": [{"content": "# A part of NonVisual Desktop Access (NVDA)\r\n# Copyright (C) 2006-2022 NV Access Limited, Bill Dengler, Joseph Lee\r\n# This file is covered by the GNU General Public License.\r\n# See the file COPYING for more details.\r\n\r\n\"\"\"A module used to record Windows versions.\r\nIt is also used to define feature checks such as\r\nmaking sure NVDA can run on a minimum supported version of Windows.\r\n\r\nWhen working on this file, consider moving to winAPI.\r\n\"\"\"\r\n\r\nfrom typing import Optional\r\nimport sys\r\nimport os\r\nimport functools\r\nimport winreg\r\n\r\n\r\n# Records a mapping between Windows builds and release names.\r\n# These include build 10240 for Windows 10 1507 and releases with multiple release builds.\r\n# These are applicable to Windows 10 and later as they report the same system version (10.0).\r\n_BUILDS_TO_RELEASE_NAMES = {\r\n\t10240: \"Windows 10 1507\",\r\n\t10586: \"Windows 10 1511\",\r\n\t14393: \"Windows 10 1607\",\r\n\t15063: \"Windows 10 1703\",\r\n\t16299: \"Windows 10 1709\",\r\n\t17134: \"Windows 10 1803\",\r\n\t17763: \"Windows 10 1809\",\r\n\t18362: \"Windows 10 1903\",\r\n\t18363: \"Windows 10 1909\",\r\n\t19041: \"Windows 10 2004\",\r\n\t19042: \"Windows 10 20H2\",\r\n\t19043: \"Windows 10 21H1\",\r\n\t19044: \"Windows 10 21H2\",\r\n\t19045: \"Windows 10 22H2\",\r\n\t20348: \"Windows Server 2022\",\r\n\t22000: \"Windows 11 21H2\",\r\n\t22621: \"Windows 11 22H2\",\r\n}\r\n\r\n\r\n@functools.lru_cache(maxsize=1)\r\ndef _getRunningVersionNameFromWinReg() -> str:\r\n\t\"\"\"Returns the Windows release name defined in Windows Registry.\r\n\tThis is applicable on Windows 10 Version 1511 (build 10586) and later.\r\n\t\"\"\"\r\n\t# Cache the version in use on the system.\r\n\twith winreg.OpenKey(\r\n\t\twinreg.HKEY_LOCAL_MACHINE, r\"Software\\Microsoft\\Windows NT\\CurrentVersion\"\r\n\t) as currentVersion:\r\n\t\t# Version 20H2 and later where a separate display version string is used.\r\n\t\ttry:\r\n\t\t\treleaseId = winreg.QueryValueEx(currentVersion, \"DisplayVersion\")[0]\r\n\t\texcept OSError:\r\n\t\t\t# Don't set anything if this is Windows 10 1507 or earlier.\r\n\t\t\ttry:\r\n\t\t\t\treleaseId = winreg.QueryValueEx(currentVersion, \"ReleaseID\")[0]\r\n\t\t\texcept OSError:\r\n\t\t\t\traise RuntimeError(\r\n\t\t\t\t\t\"Release name is not recorded in Windows Registry on this version of Windows\"\r\n\t\t\t\t) from None\r\n\treturn releaseId\r\n\r\n\r\n@functools.total_ordering\r\nclass WinVersion(object):\r\n\t\"\"\"\r\n\tRepresents a Windows release.\r\n\tIncludes version major, minor, build, service pack information,\r\n\tas well as tools such as checking for specific Windows 10 releases.\r\n\t\"\"\"\r\n\r\n\tdef __init__(\r\n\t\t\tself,\r\n\t\t\tmajor: int = 0,\r\n\t\t\tminor: int = 0,\r\n\t\t\tbuild: int = 0,\r\n\t\t\treleaseName: Optional[str] = None,\r\n\t\t\tservicePack: str = \"\",\r\n\t\t\tproductType: str = \"\"\r\n\t):\r\n\t\tself.major = major\r\n\t\tself.minor = minor\r\n\t\tself.build = build\r\n\t\tif releaseName:\r\n\t\t\tself.releaseName = releaseName\r\n\t\telse:\r\n\t\t\tself.releaseName = self._getWindowsReleaseName()\r\n\t\tself.servicePack = servicePack\r\n\t\tself.productType = productType\r\n\r\n\tdef _getWindowsReleaseName(self) -> str:\r\n\t\t\"\"\"Returns the public release name for a given Windows release based on major, minor, and build.\r\n\t\tThis is useful if release names are not defined when constructing this class.\r\n\t\tFor example, 6.1 will return 'Windows 7'.\r\n\t\tFor Windows 10, feature update release name will be included.\r\n\t\tOn server systems, unless noted otherwise, client release names will be returned.\r\n\t\tFor example, 'Windows 10 1809' will be returned on Server 2019 systems.\r\n\t\t\"\"\"\r\n\t\tif (self.major, self.minor) == (6, 1):\r\n\t\t\treturn \"Windows 7\"\r\n\t\telif (self.major, self.minor) == (6, 2):\r\n\t\t\treturn \"Windows 8\"\r\n\t\telif (self.major, self.minor) == (6, 3):\r\n\t\t\treturn \"Windows 8.1\"\r\n\t\telif self.major == 10:\r\n\t\t\t# From Version 1511 (build 10586), release Id/display version comes from Windows Registry.\r\n\t\t\t# However there are builds with no release name (Version 1507/10240)\r\n\t\t\t# or releases with different builds.\r\n\t\t\t# Look these up first before asking Windows Registry.\r\n\t\t\tif self.build in _BUILDS_TO_RELEASE_NAMES:\r\n\t\t\t\treturn _BUILDS_TO_RELEASE_NAMES[self.build]\r\n\t\t\treturn \"Windows 10 unknown\"\r\n\t\telse:\r\n\t\t\treturn \"Windows release unknown\"\r\n\r\n\tdef __repr__(self):\r\n\t\twinVersionText = [self.releaseName]\r\n\t\twinVersionText.append(f\"({self.major}.{self.minor}.{self.build})\")\r\n\t\tif self.servicePack != \"\":\r\n\t\t\twinVersionText.append(f\"service pack {self.servicePack}\")\r\n\t\tif self.productType != \"\":\r\n\t\t\twinVersionText.append(self.productType)\r\n\t\treturn \" \".join(winVersionText)\r\n\r\n\tdef __eq__(self, other):\r\n\t\treturn (\r\n\t\t\t(self.major, self.minor, self.build)\r\n\t\t\t== (other.major, other.minor, other.build)\r\n\t\t)\r\n\r\n\tdef __ge__(self, other):\r\n\t\treturn (\r\n\t\t\t(self.major, self.minor, self.build)\r\n\t\t\t>= (other.major, other.minor, other.build)\r\n\t\t)\r\n\r\n\r\n# Windows releases to WinVersion instances for easing comparisons.\r\nWIN7 = WinVersion(major=6, minor=1, build=7600)\r\nWIN7_SP1 = WinVersion(major=6, minor=1, build=7601, servicePack=\"1\")\r\nWIN8 = WinVersion(major=6, minor=2, build=9200)\r\nWIN81 = WinVersion(major=6, minor=3, build=9600)\r\nWIN10 = WIN10_1507 = WinVersion(major=10, minor=0, build=10240)\r\nWIN10_1511 = WinVersion(major=10, minor=0, build=10586)\r\nWIN10_1607 = WinVersion(major=10, minor=0, build=14393)\r\nWIN10_1703 = WinVersion(major=10, minor=0, build=15063)\r\nWIN10_1709 = WinVersion(major=10, minor=0, build=16299)\r\nWIN10_1803 = WinVersion(major=10, minor=0, build=17134)\r\nWIN10_1809 = WinVersion(major=10, minor=0, build=17763)\r\nWIN10_1903 = WinVersion(major=10, minor=0, build=18362)\r\nWIN10_1909 = WinVersion(major=10, minor=0, build=18363)\r\nWIN10_2004 = WinVersion(major=10, minor=0, build=19041)\r\nWIN10_20H2 = WinVersion(major=10, minor=0, build=19042)\r\nWIN10_21H1 = WinVersion(major=10, minor=0, build=19043)\r\nWIN10_21H2 = WinVersion(major=10, minor=0, build=19044)\r\nWIN10_22H2 = WinVersion(major=10, minor=0, build=19045)\r\nWINSERVER_2022 = WinVersion(major=10, minor=0, build=20348)\r\nWIN11 = WIN11_21H2 = WinVersion(major=10, minor=0, build=22000)\r\nWIN11_22H2 = WinVersion(major=10, minor=0, build=22621)\r\n\r\n\r\n@functools.lru_cache(maxsize=1)\r\ndef getWinVer():\r\n\t\"\"\"Returns a record of current Windows version NVDA is running on.\r\n\t\"\"\"\r\n\twinVer = sys.getwindowsversion()\r\n\t# #12509: on Windows 10, fetch whatever Windows Registry says for the current build.\r\n\t# #12626: note that not all Windows 10 releases are labeled \"Windows 10\"\r\n\t# (build 22000 is Windows 11 despite major.minor being 10.0).\r\n\ttry:\r\n\t\tif WinVersion(\r\n\t\t\tmajor=winVer.major,\r\n\t\t\tminor=winVer.minor,\r\n\t\t\tbuild=winVer.build\r\n\t\t) >= WIN11:\r\n\t\t\treleaseName = f\"Windows 11 {_getRunningVersionNameFromWinReg()}\"\r\n\t\telse:\r\n\t\t\treleaseName = f\"Windows 10 {_getRunningVersionNameFromWinReg()}\"\r\n\texcept RuntimeError:\r\n\t\treleaseName = None\r\n\treturn WinVersion(\r\n\t\tmajor=winVer.major,\r\n\t\tminor=winVer.minor,\r\n\t\tbuild=winVer.build,\r\n\t\treleaseName=releaseName,\r\n\t\tservicePack=winVer.service_pack,\r\n\t\tproductType=(\"workstation\", \"domain controller\", \"server\")[winVer.product_type - 1]\r\n\t)\r\n\r\n\r\ndef isSupportedOS():\r\n\t# NVDA can only run on Windows 7 Service pack 1 and above\r\n\treturn getWinVer() >= WIN7_SP1\r\n\r\n\r\nUWP_OCR_DATA_PATH = os.path.expandvars(r\"$windir\\OCR\")\r\n\r\n\r\ndef isUwpOcrAvailable():\r\n\treturn os.path.isdir(UWP_OCR_DATA_PATH)\r\n\r\n\r\ndef isFullScreenMagnificationAvailable() -> bool:\r\n\t\"\"\"\r\n\tTechnically this is always False. The Magnification API has been marked by MS as unsupported for\r\n\tWOW64 applications such as NVDA. For our usages, support has been added since Windows 8, relying on our\r\n\ttesting our specific usage of the API with each Windows version since Windows 8\r\n\t\"\"\"\r\n\treturn getWinVer() >= WIN8\r\n", "path": "source/winVersion.py"}], "after_files": [{"content": "# A part of NonVisual Desktop Access (NVDA)\r\n# Copyright (C) 2006-2022 NV Access Limited, Bill Dengler, Joseph Lee\r\n# This file is covered by the GNU General Public License.\r\n# See the file COPYING for more details.\r\n\r\n\"\"\"A module used to record Windows versions.\r\nIt is also used to define feature checks such as\r\nmaking sure NVDA can run on a minimum supported version of Windows.\r\n\r\nWhen working on this file, consider moving to winAPI.\r\n\"\"\"\r\n\r\nfrom typing import Optional\r\nimport sys\r\nimport os\r\nimport functools\r\nimport winreg\r\nimport platform\r\n\r\n\r\n# Records a mapping between Windows builds and release names.\r\n# These include build 10240 for Windows 10 1507 and releases with multiple release builds.\r\n# These are applicable to Windows 10 and later as they report the same system version (10.0).\r\n_BUILDS_TO_RELEASE_NAMES = {\r\n\t10240: \"Windows 10 1507\",\r\n\t10586: \"Windows 10 1511\",\r\n\t14393: \"Windows 10 1607\",\r\n\t15063: \"Windows 10 1703\",\r\n\t16299: \"Windows 10 1709\",\r\n\t17134: \"Windows 10 1803\",\r\n\t17763: \"Windows 10 1809\",\r\n\t18362: \"Windows 10 1903\",\r\n\t18363: \"Windows 10 1909\",\r\n\t19041: \"Windows 10 2004\",\r\n\t19042: \"Windows 10 20H2\",\r\n\t19043: \"Windows 10 21H1\",\r\n\t19044: \"Windows 10 21H2\",\r\n\t19045: \"Windows 10 22H2\",\r\n\t20348: \"Windows Server 2022\",\r\n\t22000: \"Windows 11 21H2\",\r\n\t22621: \"Windows 11 22H2\",\r\n}\r\n\r\n\r\n@functools.lru_cache(maxsize=1)\r\ndef _getRunningVersionNameFromWinReg() -> str:\r\n\t\"\"\"Returns the Windows release name defined in Windows Registry.\r\n\tThis is applicable on Windows 10 Version 1511 (build 10586) and later.\r\n\t\"\"\"\r\n\t# Cache the version in use on the system.\r\n\twith winreg.OpenKey(\r\n\t\twinreg.HKEY_LOCAL_MACHINE, r\"Software\\Microsoft\\Windows NT\\CurrentVersion\"\r\n\t) as currentVersion:\r\n\t\t# Version 20H2 and later where a separate display version string is used.\r\n\t\ttry:\r\n\t\t\treleaseId = winreg.QueryValueEx(currentVersion, \"DisplayVersion\")[0]\r\n\t\texcept OSError:\r\n\t\t\t# Don't set anything if this is Windows 10 1507 or earlier.\r\n\t\t\ttry:\r\n\t\t\t\treleaseId = winreg.QueryValueEx(currentVersion, \"ReleaseID\")[0]\r\n\t\t\texcept OSError:\r\n\t\t\t\traise RuntimeError(\r\n\t\t\t\t\t\"Release name is not recorded in Windows Registry on this version of Windows\"\r\n\t\t\t\t) from None\r\n\treturn releaseId\r\n\r\n\r\n@functools.total_ordering\r\nclass WinVersion(object):\r\n\t\"\"\"\r\n\tRepresents a Windows release.\r\n\tIncludes version major, minor, build, service pack information, machine architecture,\r\n\tas well as tools such as checking for specific Windows 10 releases.\r\n\t\"\"\"\r\n\r\n\tdef __init__(\r\n\t\t\tself,\r\n\t\t\tmajor: int = 0,\r\n\t\t\tminor: int = 0,\r\n\t\t\tbuild: int = 0,\r\n\t\t\treleaseName: Optional[str] = None,\r\n\t\t\tservicePack: str = \"\",\r\n\t\t\tproductType: str = \"\",\r\n\t\t\tprocessorArchitecture: str = \"\"\r\n\t):\r\n\t\tself.major = major\r\n\t\tself.minor = minor\r\n\t\tself.build = build\r\n\t\tif releaseName:\r\n\t\t\tself.releaseName = releaseName\r\n\t\telse:\r\n\t\t\tself.releaseName = self._getWindowsReleaseName()\r\n\t\tself.servicePack = servicePack\r\n\t\tself.productType = productType\r\n\t\tself.processorArchitecture = processorArchitecture\r\n\r\n\tdef _getWindowsReleaseName(self) -> str:\r\n\t\t\"\"\"Returns the public release name for a given Windows release based on major, minor, and build.\r\n\t\tThis is useful if release names are not defined when constructing this class.\r\n\t\tFor example, 6.1 will return 'Windows 7'.\r\n\t\tFor Windows 10, feature update release name will be included.\r\n\t\tOn server systems, unless noted otherwise, client release names will be returned.\r\n\t\tFor example, 'Windows 10 1809' will be returned on Server 2019 systems.\r\n\t\t\"\"\"\r\n\t\tif (self.major, self.minor) == (6, 1):\r\n\t\t\treturn \"Windows 7\"\r\n\t\telif (self.major, self.minor) == (6, 2):\r\n\t\t\treturn \"Windows 8\"\r\n\t\telif (self.major, self.minor) == (6, 3):\r\n\t\t\treturn \"Windows 8.1\"\r\n\t\telif self.major == 10:\r\n\t\t\t# From Version 1511 (build 10586), release Id/display version comes from Windows Registry.\r\n\t\t\t# However there are builds with no release name (Version 1507/10240)\r\n\t\t\t# or releases with different builds.\r\n\t\t\t# Look these up first before asking Windows Registry.\r\n\t\t\tif self.build in _BUILDS_TO_RELEASE_NAMES:\r\n\t\t\t\treturn _BUILDS_TO_RELEASE_NAMES[self.build]\r\n\t\t\treturn \"Windows 10 unknown\"\r\n\t\telse:\r\n\t\t\treturn \"Windows release unknown\"\r\n\r\n\tdef __repr__(self):\r\n\t\twinVersionText = [self.releaseName]\r\n\t\twinVersionText.append(f\"({self.major}.{self.minor}.{self.build})\")\r\n\t\tif self.servicePack != \"\":\r\n\t\t\twinVersionText.append(f\"service pack {self.servicePack}\")\r\n\t\tif self.productType != \"\":\r\n\t\t\twinVersionText.append(self.productType)\r\n\t\tif self.processorArchitecture != \"\":\r\n\t\t\twinVersionText.append(self.processorArchitecture)\r\n\t\treturn \" \".join(winVersionText)\r\n\r\n\tdef __eq__(self, other):\r\n\t\treturn (\r\n\t\t\t(self.major, self.minor, self.build)\r\n\t\t\t== (other.major, other.minor, other.build)\r\n\t\t)\r\n\r\n\tdef __ge__(self, other):\r\n\t\treturn (\r\n\t\t\t(self.major, self.minor, self.build)\r\n\t\t\t>= (other.major, other.minor, other.build)\r\n\t\t)\r\n\r\n\r\n# Windows releases to WinVersion instances for easing comparisons.\r\nWIN7 = WinVersion(major=6, minor=1, build=7600)\r\nWIN7_SP1 = WinVersion(major=6, minor=1, build=7601, servicePack=\"1\")\r\nWIN8 = WinVersion(major=6, minor=2, build=9200)\r\nWIN81 = WinVersion(major=6, minor=3, build=9600)\r\nWIN10 = WIN10_1507 = WinVersion(major=10, minor=0, build=10240)\r\nWIN10_1511 = WinVersion(major=10, minor=0, build=10586)\r\nWIN10_1607 = WinVersion(major=10, minor=0, build=14393)\r\nWIN10_1703 = WinVersion(major=10, minor=0, build=15063)\r\nWIN10_1709 = WinVersion(major=10, minor=0, build=16299)\r\nWIN10_1803 = WinVersion(major=10, minor=0, build=17134)\r\nWIN10_1809 = WinVersion(major=10, minor=0, build=17763)\r\nWIN10_1903 = WinVersion(major=10, minor=0, build=18362)\r\nWIN10_1909 = WinVersion(major=10, minor=0, build=18363)\r\nWIN10_2004 = WinVersion(major=10, minor=0, build=19041)\r\nWIN10_20H2 = WinVersion(major=10, minor=0, build=19042)\r\nWIN10_21H1 = WinVersion(major=10, minor=0, build=19043)\r\nWIN10_21H2 = WinVersion(major=10, minor=0, build=19044)\r\nWIN10_22H2 = WinVersion(major=10, minor=0, build=19045)\r\nWINSERVER_2022 = WinVersion(major=10, minor=0, build=20348)\r\nWIN11 = WIN11_21H2 = WinVersion(major=10, minor=0, build=22000)\r\nWIN11_22H2 = WinVersion(major=10, minor=0, build=22621)\r\n\r\n\r\n@functools.lru_cache(maxsize=1)\r\ndef getWinVer():\r\n\t\"\"\"Returns a record of current Windows version NVDA is running on.\r\n\t\"\"\"\r\n\twinVer = sys.getwindowsversion()\r\n\t# #12509: on Windows 10, fetch whatever Windows Registry says for the current build.\r\n\t# #12626: note that not all Windows 10 releases are labeled \"Windows 10\"\r\n\t# (build 22000 is Windows 11 despite major.minor being 10.0).\r\n\ttry:\r\n\t\tif WinVersion(\r\n\t\t\tmajor=winVer.major,\r\n\t\t\tminor=winVer.minor,\r\n\t\t\tbuild=winVer.build\r\n\t\t) >= WIN11:\r\n\t\t\treleaseName = f\"Windows 11 {_getRunningVersionNameFromWinReg()}\"\r\n\t\telse:\r\n\t\t\treleaseName = f\"Windows 10 {_getRunningVersionNameFromWinReg()}\"\r\n\texcept RuntimeError:\r\n\t\treleaseName = None\r\n\treturn WinVersion(\r\n\t\tmajor=winVer.major,\r\n\t\tminor=winVer.minor,\r\n\t\tbuild=winVer.build,\r\n\t\treleaseName=releaseName,\r\n\t\tservicePack=winVer.service_pack,\r\n\t\tproductType=(\"workstation\", \"domain controller\", \"server\")[winVer.product_type - 1],\r\n\t\tprocessorArchitecture=platform.machine()\r\n\t)\r\n\r\n\r\ndef isSupportedOS():\r\n\t# NVDA can only run on Windows 7 Service pack 1 and above\r\n\treturn getWinVer() >= WIN7_SP1\r\n\r\n\r\nUWP_OCR_DATA_PATH = os.path.expandvars(r\"$windir\\OCR\")\r\n\r\n\r\ndef isUwpOcrAvailable():\r\n\treturn os.path.isdir(UWP_OCR_DATA_PATH)\r\n\r\n\r\ndef isFullScreenMagnificationAvailable() -> bool:\r\n\t\"\"\"\r\n\tTechnically this is always False. The Magnification API has been marked by MS as unsupported for\r\n\tWOW64 applications such as NVDA. For our usages, support has been added since Windows 8, relying on our\r\n\ttesting our specific usage of the API with each Windows version since Windows 8\r\n\t\"\"\"\r\n\treturn getWinVer() >= WIN8\r\n", "path": "source/winVersion.py"}]}