Repository: nvaccess/nvda

Issue:
Use winVersion.getWinVer().processorArchitecture whenever possible

### Is your feature request related to a problem? Please describe.
With #14439, it is possible to obtain processor architecture for the Windows instalaltion. This can replace os.environ["PROCESSOR_ARCHITEW6432"] in most situations. Currently environmetn variable is read in app module (is64BitProcess), COM registration fixing tool, and NVDA Helper library initialization.

### Describe the solution you'd like
Use processor architecture string whenever possible. The only exception is update check where due to service pack string, sys.getwindowsversion() must be employed until NVDA moves to supporting Windows 8/10 and later. Or, provided that Windows 7 SP1 reports service pack minor version of 0 all the time, then winVersion.getWinVer() can be used in update check (note that on 32-bit systems, architecture string to be sent to NV Access server is empty).

### Describe alternatives you've considered
Leave things as is.

### Additional context
Checking for 64-bit Windows can be done by either:

* winVersion.getWinVer().processorArchitecture in ("AMD64", "ARM64")
* winVersion.getWinVer().processorArchitecture.endswith("64")



Discussion:

Resolving patch:
diff --git a/source/COMRegistrationFixes/__init__.py b/source/COMRegistrationFixes/__init__.py
--- a/source/COMRegistrationFixes/__init__.py
+++ b/source/COMRegistrationFixes/__init__.py
@@ -1,5 +1,5 @@
 # A part of NonVisual Desktop Access (NVDA)
-# Copyright (C) 2018-2021 NV Access Limited, Luke Davis (Open Source Systems, Ltd.)
+# Copyright (C) 2018-2023 NV Access Limited, Luke Davis (Open Source Systems, Ltd.)
 # This file is covered by the GNU General Public License.
 # See the file COPYING for more details.
 
@@ -110,13 +110,13 @@ def apply64bitRegistryPatch(fileName: str) -> None:
 		log.debug(f"Applied 64-bit registry patch from {fileName}")
 
 
-def fixCOMRegistrations():
+def fixCOMRegistrations() -> None:
 	"""Registers most common COM proxies, in case they have accidentally been unregistered or overwritten by
 	3rd party software installs or uninstalls.
 	"""
-	is64bit = os.environ.get("PROCESSOR_ARCHITEW6432", "").endswith("64")
 	winVer = winVersion.getWinVer()
 	OSMajorMinor = (winVer.major, winVer.minor)
+	is64bit = winVer.processorArchitecture.endswith("64")
 	log.debug(
 		f"Fixing COM registrations for Windows {OSMajorMinor[0]}.{OSMajorMinor[1]}, "
 		"{} bit.".format("64" if is64bit else "32")
diff --git a/source/NVDAHelper.py b/source/NVDAHelper.py
--- a/source/NVDAHelper.py
+++ b/source/NVDAHelper.py
@@ -1,5 +1,5 @@
 # A part of NonVisual Desktop Access (NVDA)
-# Copyright (C) 2008-2022 NV Access Limited, Peter Vagner, Davy Kager, Mozilla Corporation, Google LLC,
+# Copyright (C) 2008-2023 NV Access Limited, Peter Vagner, Davy Kager, Mozilla Corporation, Google LLC,
 # Leonard de Ruijter
 # This file is covered by the GNU General Public License.
 # See the file COPYING for more details.
@@ -528,7 +528,7 @@ def terminate(self):
 		winKernel.closeHandle(self._process)
 
 
-def initialize():
+def initialize() -> None:
 	global _remoteLib, _remoteLoaderAMD64, _remoteLoaderARM64
 	global localLib, generateBeep, VBuf_getTextInRange, lastLanguageID, lastLayoutString
 	hkl=c_ulong(windll.User32.GetKeyboardLayout(0)).value
@@ -595,7 +595,7 @@ def initialize():
 	#Manually start the in-process manager thread for this NVDA main thread now, as a slow system can cause this action to confuse WX
 	_remoteLib.initInprocManagerThreadIfNeeded()
 	versionedLibARM64Path
-	arch = os.environ.get('PROCESSOR_ARCHITEW6432')
+	arch = winVersion.getWinVer().processorArchitecture
 	if arch == 'AMD64':
 		_remoteLoaderAMD64 = _RemoteLoader(versionedLibAMD64Path)
 	elif arch == 'ARM64':
diff --git a/source/appModuleHandler.py b/source/appModuleHandler.py
--- a/source/appModuleHandler.py
+++ b/source/appModuleHandler.py
@@ -1,6 +1,6 @@
 # -*- coding: UTF-8 -*-
 # A part of NonVisual Desktop Access (NVDA)
-# Copyright (C) 2006-2022 NV Access Limited, Peter Vágner, Aleksey Sadovoy, Patrick Zajda, Joseph Lee,
+# Copyright (C) 2006-2023 NV Access Limited, Peter Vágner, Aleksey Sadovoy, Patrick Zajda, Joseph Lee,
 # Babbage B.V., Mozilla Corporation, Julien Cochuyt, Leonard de Ruijter
 # This file is covered by the GNU General Public License.
 # See the file COPYING for more details.
@@ -628,11 +628,11 @@ def _get_appPath(self):
 		self.appPath = path.value if path else None
 		return self.appPath
 
-	def _get_is64BitProcess(self):
+	def _get_is64BitProcess(self) -> bool:
 		"""Whether the underlying process is a 64 bit process.
 		@rtype: bool
 		"""
-		if os.environ.get("PROCESSOR_ARCHITEW6432") not in ("AMD64","ARM64"):
+		if winVersion.getWinVer().processorArchitecture not in ("AMD64", "ARM64"):
 			# This is 32 bit Windows.
 			self.is64BitProcess = False
 			return False
@@ -733,7 +733,7 @@ def _get_appArchitecture(self) -> str:
 				processMachine = ctypes.wintypes.USHORT()
 				ctypes.windll.kernel32.IsWow64Process2(self.processHandle, ctypes.byref(processMachine), None)
 				if not processMachine.value:
-					self.appArchitecture = os.environ.get("PROCESSOR_ARCHITEW6432")
+					self.appArchitecture = winVersion.getWinVer().processorArchitecture
 				else:
 					# On ARM64, two 32-bit architectures are supported: x86 (via emulation) and ARM (natively).
 					self.appArchitecture = archValues2ArchNames[processMachine.value]


Test patch: