#!/usr/bin/python #-*- coding: utf-8 -*- import os import sys import shutil import cocos import re import zipfile VS_VERSION_MAP = { 2012 : "11.0", 2013 : "12.0", 2015 : "14.0", 2017 : "15.0" } def get_msbuild_path(vs_version): if cocos.os_is_win32(): import _winreg else: return None if isinstance(vs_version, int): # The value of vs_version is int. such as : 2017 if vs_version in VS_VERSION_MAP.keys(): vs_ver = VS_VERSION_MAP[vs_version] else: # not supported VS version return None elif isinstance(vs_version, str): # The value of vs_version is string. such as: "12.0", "14.0" vs_ver = vs_version else: return None # If the system is 64bit, find VS in both 32bit & 64bit registry # If the system is 32bit, only find VS in 32bit registry if cocos.os_is_32bit_windows(): reg_flag_list = [ _winreg.KEY_WOW64_32KEY ] else: reg_flag_list = [ _winreg.KEY_WOW64_64KEY, _winreg.KEY_WOW64_32KEY ] # Find VS path msbuild_path = None for reg_flag in reg_flag_list: try: vs = _winreg.OpenKey( _winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\MSBuild\ToolsVersions\%s" % vs_ver, 0, _winreg.KEY_READ | reg_flag ) msbuild_path, type = _winreg.QueryValueEx(vs, 'MSBuildToolsPath') except: continue if msbuild_path is not None: msbuild_path = os.path.join(msbuild_path, "MSBuild.exe") if os.path.exists(msbuild_path): break else: msbuild_path = None return msbuild_path def get_devenv_path(vs_version): if cocos.os_is_win32(): import _winreg else: return None if isinstance(vs_version, int): # The value of vs_version is int. such as : 2017 if vs_version in VS_VERSION_MAP.keys(): vs_ver = VS_VERSION_MAP[vs_version] else: # not supported VS version return None elif isinstance(vs_version, str): # The value of vs_version is string. such as: "12.0", "14.0" vs_ver = vs_version else: return None # If the system is 64bit, find VS in both 32bit & 64bit registry # If the system is 32bit, only find VS in 32bit registry if cocos.os_is_32bit_windows(): reg_flag_list = [ _winreg.KEY_WOW64_32KEY ] else: reg_flag_list = [ _winreg.KEY_WOW64_64KEY, _winreg.KEY_WOW64_32KEY ] devenv_path = None for reg_flag in reg_flag_list: try: vs = _winreg.OpenKey( _winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\VisualStudio", 0, _winreg.KEY_READ | reg_flag ) except: continue # find specified VS try: key = _winreg.OpenKey(vs, r"SxS\VS7") devenv_path, type = _winreg.QueryValueEx(key, vs_ver) except: pass if devenv_path is not None: devenv_path = os.path.join(devenv_path, "Common7", "IDE", "devenv.com") if os.path.exists(devenv_path): break else: devenv_path = None return devenv_path def get_vs_versions(): # Get the VS versions ret = [] if cocos.os_is_win32(): import _winreg else: return ret # If the system is 64bit, find VS in both 32bit & 64bit registry # If the system is 32bit, only find VS in 32bit registry if cocos.os_is_32bit_windows(): reg_flag_list = [ _winreg.KEY_WOW64_32KEY ] else: reg_flag_list = [ _winreg.KEY_WOW64_64KEY, _winreg.KEY_WOW64_32KEY ] version_pattern = re.compile(r'(\d+)\.(\d+)') for reg_flag in reg_flag_list: try: vs = _winreg.OpenKey( _winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\VisualStudio", 0, _winreg.KEY_READ | reg_flag ) except: continue i = 0 while True: # enum the keys in vs reg try: version = _winreg.EnumKey(vs, i) except: break i += 1 match = re.match(version_pattern, version) if match is None: continue ver_str = '%s.%s' % (match.group(1), match.group(2)) if ver_str not in ret: ret.append(ver_str) return ret def get_newest_msbuild(min_ver=None): versions = get_vs_versions() min_ver_float = 0.0 if isinstance(min_ver, str): # value of min_ver is string. such as : "12.0", "14.0" min_ver_float = float(min_ver) elif isinstance(min_ver, int) and min_ver in VS_VERSION_MAP.keys(): # value of min_ver is int. such as : 2017 min_ver_float = float(VS_VERSION_MAP[min_ver]) find_ver = None find_path = None for v in versions: cur_v = float(v) if cur_v < min_ver_float: continue v_path = get_msbuild_path(v) if v_path is not None: if (find_ver is None) or (cur_v > find_ver): find_ver = cur_v find_path = v_path return find_path def get_newest_devenv(min_ver=None): versions = get_vs_versions() min_ver_float = 0.0 if isinstance(min_ver, str): # value of min_ver is string. such as : "12.0", "14.0" min_ver_float = float(min_ver) elif isinstance(min_ver, int) and min_ver in VS_VERSION_MAP.keys(): # value of min_ver is int. such as : 2017 min_ver_float = float(VS_VERSION_MAP[min_ver]) find_ver = None find_path = None for v in versions: cur_v = float(v) if cur_v < min_ver_float: continue v_path = get_devenv_path(v) if v_path is not None: if (find_ver is None) or (cur_v > find_ver): find_ver = cur_v find_path = v_path if min_ver_float > 0 and find_ver > min_ver_float: need_upgrade = True else: need_upgrade = False return (need_upgrade, find_path) def rmdir(folder): if os.path.exists(folder): if sys.platform == 'win32': cocos.CMDRunner.run_cmd("rd /s/q \"%s\"" % folder, verbose=True) else: shutil.rmtree(folder) VERSION_FILE_PATH = 'cocos/cocos2d.cpp' VERSION_PATTERN = r".*return[ \t]+\"(.*)\";" def get_engine_version(engine_path): ret = None try: version_file = os.path.join(engine_path, VERSION_FILE_PATH) if os.path.isfile(version_file): f = open(version_file) for line in f.readlines(): match = re.match(VERSION_PATTERN, line) if match: ret = match.group(1) break f.close() except: pass return ret def un_zip(file_name, output_dir): """unzip zip file into output_dir""" zip_file = zipfile.ZipFile(file_name) for names in zip_file.namelist(): zip_file.extract(names, output_dir) zip_file.close() class ExtendEnv(object): extend_env = {} @classmethod def parse_extend_env(cls, env): env_list = env.split(';') for item in env_list: index = item.find('=') if index > 0: key = item[:index] value = item[index+1:] cls.extend_env[key] = value @classmethod def get_extend_env_value(cls, key): if (cls.extend_env.has_key(key)): return cls.extend_env[key] else: return None @classmethod def get_extend_env_str(cls): env_list = [] for item in cls.extend_env: env_list.append("%s=%s" % (item, cls.extend_env[item])) return ';'.join(env_list)