From 59141963d2942c533c9eb8f83d22decfafc25151 Mon Sep 17 00:00:00 2001 From: Anderson Carlos Ferreira da Silva Date: Fri, 24 Mar 2023 11:08:42 +0100 Subject: [PATCH 1/5] detecting os and windows path --- chromedriver_binary/utils.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/chromedriver_binary/utils.py b/chromedriver_binary/utils.py index 3d9a653..00f16c8 100644 --- a/chromedriver_binary/utils.py +++ b/chromedriver_binary/utils.py @@ -111,14 +111,24 @@ def get_chrome_major_version(): if sys.platform == "darwin": browser_executables.insert(0, "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome") + get_raw_version = lambda executable: subprocess.check_output([executable, '--version']) + get_parsed_version = lambda version: re.match(r'.*?((?P\d+)\.(\d+\.){2,3}\d+).*?', version.decode('utf-8')).group('major') + get_major_version = lambda executable: get_parsed_version(get_raw_version(executable)) + for browser_executable in browser_executables: try: - version = subprocess.check_output([browser_executable, '--version']) - return re.match(r'.*?((?P\d+)\.(\d+\.){2,3}\d+).*?', version.decode('utf-8')).group('major') + return get_major_version(browser_executable) except Exception: + if sys.platform.startswith('win'): + roots = filter(None, [os.getenv('LocalAppData'), os.getenv('ProgramFiles'), os.getenv('ProgramFiles(x86)'), os.getenv('ProgramW6432')]) + + for root in roots: + try: + return get_major_version(os.path.join(root, 'Google', 'Chrome', 'Application', browser_executable + '.exe')) + except Exception: + pass pass - def check_version(binary, required_version): try: version = subprocess.check_output([binary, '-v']) From 8d2cb7aa71bda716f652f30033a6f34fc9642435 Mon Sep 17 00:00:00 2001 From: Anderson Carlos Ferreira da Silva Date: Fri, 24 Mar 2023 13:35:11 +0100 Subject: [PATCH 2/5] debugging (#1) testing and debugging --- chromedriver_binary/utils.py | 37 ++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/chromedriver_binary/utils.py b/chromedriver_binary/utils.py index 00f16c8..8ecb320 100644 --- a/chromedriver_binary/utils.py +++ b/chromedriver_binary/utils.py @@ -9,6 +9,8 @@ import subprocess import re import platform +import array +import ctypes try: from urllib.request import urlopen, URLError @@ -111,20 +113,43 @@ def get_chrome_major_version(): if sys.platform == "darwin": browser_executables.insert(0, "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome") - get_raw_version = lambda executable: subprocess.check_output([executable, '--version']) - get_parsed_version = lambda version: re.match(r'.*?((?P\d+)\.(\d+\.){2,3}\d+).*?', version.decode('utf-8')).group('major') - get_major_version = lambda executable: get_parsed_version(get_raw_version(executable)) + get_version = lambda version: re.match(r'.*?((?P\d+)\.(\d+\.){2,3}\d+).*?', version).group('major') for browser_executable in browser_executables: try: - return get_major_version(browser_executable) + version = subprocess.check_output([browser_executable, '--version']) + + return get_version(version.decode('utf-8')) + except Exception: if sys.platform.startswith('win'): - roots = filter(None, [os.getenv('LocalAppData'), os.getenv('ProgramFiles'), os.getenv('ProgramFiles(x86)'), os.getenv('ProgramW6432')]) + roots = list(filter(None, [os.getenv('LocalAppData'), os.getenv('ProgramFiles'), os.getenv('ProgramFiles(x86)'), os.getenv('ProgramW6432')])) for root in roots: try: - return get_major_version(os.path.join(root, 'Google', 'Chrome', 'Application', browser_executable + '.exe')) + # https://stackoverflow.com/questions/580924/how-to-access-a-files-properties-on-windows + document = ctypes.wstring_at(os.path.join(root, 'Google', 'Chrome', 'Application', browser_executable + '.exe')) + + buffer_size = ctypes.windll.version.GetFileVersionInfoSizeW(document, None) + buffer = ctypes.create_string_buffer(buffer_size) + + ctypes.windll.version.GetFileVersionInfoW(document, None, buffer_size, buffer) + + value_size = ctypes.c_uint(0) + value = ctypes.c_void_p(0) + + ctypes.windll.version.VerQueryValueW(buffer, ctypes.wstring_at(r"\VarFileInfo\Translation"), ctypes.byref(value), ctypes.byref(value_size)) + + codepages = array.array('H', ctypes.string_at(value.value, value_size.value)) + + language = '{0:04x}{1:04x}'.format(*codepages[:2].tolist()) + + ctypes.windll.version.VerQueryValueW(buffer, ctypes.wstring_at('\\StringFileInfo\\' + language + '\\FileVersion'), ctypes.byref(value), ctypes.byref(value_size)) + + version = ctypes.wstring_at(value.value, value_size.value - 1) + + return get_version(version) + except Exception: pass pass From 636dffbda471faf8e508194865a42e90ef8d81b7 Mon Sep 17 00:00:00 2001 From: Anderson Carlos Ferreira da Silva Date: Fri, 24 Mar 2023 15:59:06 +0100 Subject: [PATCH 3/5] adding support to Python 2 (#2) adding support to Python 2 --- chromedriver_binary/utils.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/chromedriver_binary/utils.py b/chromedriver_binary/utils.py index 8ecb320..9af9bbd 100644 --- a/chromedriver_binary/utils.py +++ b/chromedriver_binary/utils.py @@ -123,30 +123,41 @@ def get_chrome_major_version(): except Exception: if sys.platform.startswith('win'): + get_info_size = ctypes.windll.version.GetFileVersionInfoSizeW + get_info = ctypes.windll.version.GetFileVersionInfoW + get_value = ctypes.windll.version.VerQueryValueW + get_string = ctypes.wstring_at + + if sys.version_info.major < 3: + get_info_size = ctypes.windll.version.GetFileVersionInfoSizeA + get_info = ctypes.windll.version.GetFileVersionInfoA + get_value = ctypes.windll.version.VerQueryValueA + get_string = ctypes.string_at + roots = list(filter(None, [os.getenv('LocalAppData'), os.getenv('ProgramFiles'), os.getenv('ProgramFiles(x86)'), os.getenv('ProgramW6432')])) - + for root in roots: try: # https://stackoverflow.com/questions/580924/how-to-access-a-files-properties-on-windows document = ctypes.wstring_at(os.path.join(root, 'Google', 'Chrome', 'Application', browser_executable + '.exe')) - buffer_size = ctypes.windll.version.GetFileVersionInfoSizeW(document, None) + buffer_size = get_info_size(document, None) buffer = ctypes.create_string_buffer(buffer_size) - ctypes.windll.version.GetFileVersionInfoW(document, None, buffer_size, buffer) + get_info(document, None, buffer_size, buffer) value_size = ctypes.c_uint(0) value = ctypes.c_void_p(0) - ctypes.windll.version.VerQueryValueW(buffer, ctypes.wstring_at(r"\VarFileInfo\Translation"), ctypes.byref(value), ctypes.byref(value_size)) + get_value(buffer, get_string(r"\VarFileInfo\Translation"), ctypes.byref(value), ctypes.byref(value_size)) codepages = array.array('H', ctypes.string_at(value.value, value_size.value)) language = '{0:04x}{1:04x}'.format(*codepages[:2].tolist()) - ctypes.windll.version.VerQueryValueW(buffer, ctypes.wstring_at('\\StringFileInfo\\' + language + '\\FileVersion'), ctypes.byref(value), ctypes.byref(value_size)) + get_value(buffer, get_string('\\StringFileInfo\\' + language + '\\FileVersion'), ctypes.byref(value), ctypes.byref(value_size)) - version = ctypes.wstring_at(value.value, value_size.value - 1) + version = get_string(value.value, value_size.value - 1) return get_version(version) From 844d40bb9a0c2fe9489d9695639a50ac52f789a6 Mon Sep 17 00:00:00 2001 From: Anderson Carlos Ferreira da Silva Date: Sat, 1 Apr 2023 13:46:55 +0200 Subject: [PATCH 4/5] renaming major version function and adding support to cygwin --- chromedriver_binary/utils.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/chromedriver_binary/utils.py b/chromedriver_binary/utils.py index 9af9bbd..b316835 100644 --- a/chromedriver_binary/utils.py +++ b/chromedriver_binary/utils.py @@ -113,16 +113,16 @@ def get_chrome_major_version(): if sys.platform == "darwin": browser_executables.insert(0, "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome") - get_version = lambda version: re.match(r'.*?((?P\d+)\.(\d+\.){2,3}\d+).*?', version).group('major') + get_major_version = lambda version: re.match(r'.*?((?P\d+)\.(\d+\.){2,3}\d+).*?', version).group('major') for browser_executable in browser_executables: try: version = subprocess.check_output([browser_executable, '--version']) - return get_version(version.decode('utf-8')) + return get_major_version(version.decode('utf-8')) except Exception: - if sys.platform.startswith('win'): + if sys.platform.startswith('win') or sys.platform.startswith('cygwin'): get_info_size = ctypes.windll.version.GetFileVersionInfoSizeW get_info = ctypes.windll.version.GetFileVersionInfoW get_value = ctypes.windll.version.VerQueryValueW @@ -159,7 +159,7 @@ def get_chrome_major_version(): version = get_string(value.value, value_size.value - 1) - return get_version(version) + return get_major_version(version) except Exception: pass From ff3ad3c318d3cf726147f4051891c28d622efeb3 Mon Sep 17 00:00:00 2001 From: Anderson Carlos Ferreira da Silva Date: Tue, 22 Aug 2023 15:56:50 +0900 Subject: [PATCH 5/5] Update utils.py --- chromedriver_binary/utils.py | 60 +++++++++++++----------------------- 1 file changed, 22 insertions(+), 38 deletions(-) diff --git a/chromedriver_binary/utils.py b/chromedriver_binary/utils.py index b316835..7acd7c6 100644 --- a/chromedriver_binary/utils.py +++ b/chromedriver_binary/utils.py @@ -123,48 +123,32 @@ def get_chrome_major_version(): except Exception: if sys.platform.startswith('win') or sys.platform.startswith('cygwin'): - get_info_size = ctypes.windll.version.GetFileVersionInfoSizeW - get_info = ctypes.windll.version.GetFileVersionInfoW - get_value = ctypes.windll.version.VerQueryValueW - get_string = ctypes.wstring_at - - if sys.version_info.major < 3: - get_info_size = ctypes.windll.version.GetFileVersionInfoSizeA - get_info = ctypes.windll.version.GetFileVersionInfoA - get_value = ctypes.windll.version.VerQueryValueA - get_string = ctypes.string_at - - roots = list(filter(None, [os.getenv('LocalAppData'), os.getenv('ProgramFiles'), os.getenv('ProgramFiles(x86)'), os.getenv('ProgramW6432')])) - - for root in roots: - try: - # https://stackoverflow.com/questions/580924/how-to-access-a-files-properties-on-windows - document = ctypes.wstring_at(os.path.join(root, 'Google', 'Chrome', 'Application', browser_executable + '.exe')) - - buffer_size = get_info_size(document, None) - buffer = ctypes.create_string_buffer(buffer_size) - - get_info(document, None, buffer_size, buffer) - - value_size = ctypes.c_uint(0) - value = ctypes.c_void_p(0) - - get_value(buffer, get_string(r"\VarFileInfo\Translation"), ctypes.byref(value), ctypes.byref(value_size)) - - codepages = array.array('H', ctypes.string_at(value.value, value_size.value)) - - language = '{0:04x}{1:04x}'.format(*codepages[:2].tolist()) + try: + import winreg + with winreg.OpenKeyEx(winreg.HKEY_CURRENT_USER, r"Software\Google\Chrome\BLBeacon") as key: + version = winreg.QueryValueEx(key, "version")[0] - get_value(buffer, get_string('\\StringFileInfo\\' + language + '\\FileVersion'), ctypes.byref(value), ctypes.byref(value_size)) - - version = get_string(value.value, value_size.value - 1) - return get_major_version(version) - - except Exception: - pass + + except Exception: + roots = list(filter(None, [os.getenv('LocalAppData'), os.getenv('ProgramFiles'), os.getenv('ProgramFiles(x86)'), os.getenv('ProgramW6432')])) + + for root in roots: + try: + # https://stackoverflow.com/questions/580924/how-to-access-a-files-properties-on-windows + document = os.path.join(root, 'Google', 'Chrome', 'Application', browser_executable + '.exe') + + name = document.replace(os.path.sep, f'{os.path.sep}{os.path.sep}') + + version = subprocess.check_output(['wmic', 'datafile', 'where', f'name="{name}"', 'get', 'Version', '/value']) + + return get_major_version(version.decode('utf-8').strip()) + + except Exception: + pass pass + def check_version(binary, required_version): try: version = subprocess.check_output([binary, '-v'])