| Index: win_toolchain/get_toolchain_if_necessary.py
|
| diff --git a/win_toolchain/get_toolchain_if_necessary.py b/win_toolchain/get_toolchain_if_necessary.py
|
| index 27fa18120dd11acf5903470bf8ef46758c0f279e..e86c81f624393d9f4ec93c96fa2f7227cac6ee36 100755
|
| --- a/win_toolchain/get_toolchain_if_necessary.py
|
| +++ b/win_toolchain/get_toolchain_if_necessary.py
|
| @@ -30,6 +30,8 @@ import hashlib
|
| import json
|
| import optparse
|
| import os
|
| +import platform
|
| +import re
|
| import shutil
|
| import subprocess
|
| import sys
|
| @@ -217,6 +219,71 @@ def DoTreeMirror(target_dir, tree_sha1):
|
| RmDir(temp_dir)
|
|
|
|
|
| +def GetInstallerName():
|
| + """Return the name of the Windows 10 Universal C Runtime installer for the
|
| + current platform, or None if installer is not needed or not applicable.
|
| + The registry has to be used instead of sys.getwindowsversion() because
|
| + Python 2.7 is only manifested as being compatible up to Windows 8, so the
|
| + version APIs helpfully return a maximum of 6.2 (Windows 8).
|
| + """
|
| + ver_re = re.compile('.*REG_SZ * (\d+)\.(\d+)')
|
| + key_name = '"HKLM\Software\Microsoft\Windows NT\CurrentVersion"'
|
| + output = subprocess.check_output('reg query %s /v CurrentVersion' % key_name)
|
| + match = ver_re.match(output.replace('\n', ' '))
|
| + if match.groups() == ('6', '1'):
|
| + # Windows 7 and Windows Server 2008 R2
|
| + return 'Windows6.1-KB2999226-x64.msu'
|
| + elif match.groups() == ('6', '2'):
|
| + # Windows 8 and Windows Server 2012
|
| + return 'Windows8-RT-KB2999226-x64.msu'
|
| + elif match.groups() == ('6', '3'):
|
| + # Windows 8.1 and Windows Server 2012 R2
|
| + return 'Windows8.1-KB2999226-x64.msu'
|
| + else:
|
| + # Windows 10 or higher assumed
|
| + return None
|
| +
|
| +
|
| +def InstallUniversalCRTIfNeeded(abs_target_dir):
|
| + installer_name = GetInstallerName()
|
| + if not installer_name:
|
| + # Assumed to be Windows 10+ so nothing to do
|
| + return
|
| +
|
| + bitness = platform.architecture()[0]
|
| + # When running 64-bit python the x64 DLLs will be in System32
|
| + x64_path = 'System32' if bitness == '64bit' else 'Sysnative'
|
| + x64_path = os.path.join(r'C:\Windows', x64_path)
|
| + sample_crt_file = os.path.join(x64_path, 'api-ms-win-crt-math-l1-1-0.dll')
|
| +
|
| + if os.path.exists(sample_crt_file):
|
| + # Nothing to do.
|
| + return
|
| +
|
| + print ('%s does not exist - installing Windows 10 Universal C Runtime' %
|
| + sample_crt_file)
|
| +
|
| + installer = os.path.join(abs_target_dir, "installers", installer_name)
|
| + command = r'wusa.exe /quiet "%s"' % installer
|
| + print 'Running %s' % command
|
| +
|
| + try:
|
| + subprocess.check_call(command)
|
| + except WindowsError as e:
|
| + if e.winerror == 740: # The requested operation requires elevation
|
| + print
|
| + print '-'*80
|
| + print
|
| + print 'Elevation required. You must manually install this update:'
|
| + print ' %s' % installer
|
| + print
|
| + print '-'*80
|
| + print
|
| + raise Exception('Elevation required. You must manually install %s' %
|
| + installer)
|
| + raise e
|
| +
|
| +
|
| def main():
|
| parser = optparse.OptionParser(description=sys.modules[__name__].__doc__)
|
| parser.add_option('--output-json', metavar='FILE',
|
| @@ -331,6 +398,8 @@ def main():
|
| shutil.copyfile(os.path.join(target_dir, '..', 'data.json'),
|
| options.output_json)
|
|
|
| + InstallUniversalCRTIfNeeded(abs_target_dir)
|
| +
|
| return 0
|
|
|
|
|
|
|