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) |
scottmg
2016/01/14 21:49:59
Can you do this with https://docs.python.org/2/lib
brucedawson
2016/01/14 22:22:02
Done.
|
+ 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 '-'*80 |
+ print 'Elevation required. You must manually install this update:' |
+ print ' %s' % installer |
+ print '-'*80 |
+ 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 |