OLD | NEW |
---|---|
(Empty) | |
1 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
2 # Use of this source code is governed by a BSD-style license that can be | |
3 # found in the LICENSE file. | |
4 | |
5 import errno | |
6 import os | |
7 import re | |
8 import subprocess | |
9 import sys | |
10 | |
11 """ | |
12 This script searches for Visual Studio versions on the current system. | |
13 | |
14 Pass in the preferred VS version on the command line, or pass "auto" for | |
15 autodetect. | |
16 | |
17 This script prints a string containing the VS root directory. On failure it | |
18 returns the empty string. | |
19 """ | |
20 | |
21 def _ConvertToCygpath(path): | |
22 """Convert to cygwin path if we are using cygwin.""" | |
23 if sys.platform == 'cygwin': | |
24 p = subprocess.Popen(['cygpath', path], stdout=subprocess.PIPE) | |
25 path = p.communicate()[0].strip() | |
26 return path | |
27 | |
28 | |
29 def _RegistryQueryBase(sysdir, key, value): | |
30 """Use reg.exe to read a particular key. | |
31 | |
32 While ideally we might use the win32 module, we would like gyp to be | |
33 python neutral, so for instance cygwin python lacks this module. | |
34 | |
35 Arguments: | |
36 sysdir: The system subdirectory to attempt to launch reg.exe from. | |
37 key: The registry key to read from. | |
38 value: The particular value to read. | |
39 Return: | |
40 stdout from reg.exe, or None for failure. | |
41 """ | |
42 # Setup params to pass to and attempt to launch reg.exe | |
43 cmd = [os.path.join(os.environ.get('WINDIR', ''), sysdir, 'reg.exe'), | |
44 'query', key] | |
45 if value: | |
46 cmd.extend(['/v', value]) | |
47 p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
48 # Obtain the stdout from reg.exe, reading to the end so p.returncode is valid | |
49 # Note that the error text may be in [1] in some cases | |
50 text = p.communicate()[0] | |
51 # Check return code from reg.exe; officially 0==success and 1==error | |
52 if p.returncode: | |
53 return None | |
54 return text | |
55 | |
56 | |
57 def _RegistryQuery(key, value=None): | |
58 """Use reg.exe to read a particular key through _RegistryQueryBase. | |
59 | |
60 First tries to launch from %WinDir%\Sysnative to avoid WoW64 redirection. If | |
61 that fails, it falls back to System32. Sysnative is available on Vista and | |
62 up and available on Windows Server 2003 and XP through KB patch 942589. Note | |
63 that Sysnative will always fail if using 64-bit python due to it being a | |
64 virtual directory and System32 will work correctly in the first place. | |
65 | |
66 KB 942589 - http://support.microsoft.com/kb/942589/en-us. | |
67 | |
68 Arguments: | |
69 key: The registry key. | |
70 value: The particular registry value to read (optional). | |
71 Return: | |
72 stdout from reg.exe, or None for failure. | |
73 """ | |
74 text = None | |
75 try: | |
76 text = _RegistryQueryBase('Sysnative', key, value) | |
77 except OSError, e: | |
78 if e.errno == errno.ENOENT: | |
79 text = _RegistryQueryBase('System32', key, value) | |
80 else: | |
81 raise | |
82 return text | |
83 | |
84 | |
85 def _RegistryGetValue(key, value): | |
86 """Use reg.exe to obtain the value of a registry key. | |
87 | |
88 Args: | |
89 key: The registry key. | |
90 value: The particular registry value to read. | |
91 Return: | |
92 contents of the registry key's value, or None on failure. | |
93 """ | |
94 text = _RegistryQuery(key, value) | |
95 if not text: | |
96 return None | |
97 # Extract value. | |
98 match = re.search(r'REG_\w+\s+([^\r]+)\r\n', text) | |
99 if not match: | |
100 return None | |
101 return match.group(1) | |
102 | |
103 | |
104 def _DetectVisualStudioVersion(versions_to_check, force_express): | |
105 """Gets the path of the preferred Visual Studio version. | |
106 | |
107 Returns: | |
108 The base path of Visual Studio based on the registry and a quick check if | |
109 devenv.exe exists. | |
110 | |
111 Possibilities are: | |
112 2005(e) - Visual Studio 2005 (8) | |
113 2008(e) - Visual Studio 2008 (9) | |
scottmg
2014/01/08 00:28:30
delete 2005/2008.
| |
114 2010(e) - Visual Studio 2010 (10) | |
115 2012(e) - Visual Studio 2012 (11) | |
116 2013(e) - Visual Studio 2013 (12) | |
117 Where (e) is e for express editions of MSVS and blank otherwise. | |
118 """ | |
119 versions = [] | |
120 for version in versions_to_check: | |
121 # Old method of searching for which VS version is installed | |
122 # We don't use the 2010-encouraged-way because we also want to get the | |
123 # path to the binaries, which it doesn't offer. | |
124 keys = [r'HKLM\Software\Microsoft\VisualStudio\%s' % version, | |
125 r'HKLM\Software\Wow6432Node\Microsoft\VisualStudio\%s' % version, | |
126 r'HKLM\Software\Microsoft\VCExpress\%s' % version, | |
127 r'HKLM\Software\Wow6432Node\Microsoft\VCExpress\%s' % version] | |
128 for index in range(len(keys)): | |
129 path = _RegistryGetValue(keys[index], 'InstallDir') | |
130 if not path: | |
131 continue | |
132 path = _ConvertToCygpath(path) | |
133 # Check for full. | |
134 full_path = os.path.join(path, 'devenv.exe') | |
135 express_path = os.path.join(path, '*express.exe') | |
136 if not force_express and os.path.exists(full_path): | |
137 return os.path.normpath(os.path.join(path, '..', '..')) | |
138 # Check for express. | |
139 elif glob.glob(express_path): | |
140 return os.path.normpath(os.path.join(path, '..', '..')) | |
141 | |
142 # The old method above does not work when only SDK is installed. | |
143 keys = [r'HKLM\Software\Microsoft\VisualStudio\SxS\VC7', | |
144 r'HKLM\Software\Wow6432Node\Microsoft\VisualStudio\SxS\VC7'] | |
145 for index in range(len(keys)): | |
146 path = _RegistryGetValue(keys[index], version) | |
147 if not path: | |
148 continue | |
149 path = _ConvertToCygpath(path) | |
150 return os.path.normpath(os.path.join(path, '..')) | |
151 | |
152 return None | |
153 | |
154 if len(sys.argv) != 2: | |
155 print 'Usage: get_visual_studio_path.py <version>' | |
156 print 'Use "auto" for the version to autodetect.' | |
157 sys.exit(2) | |
158 version_map = { | |
159 'auto': ('10.0', '12.0', '9.0', '8.0', '11.0'), | |
scottmg
2014/01/08 00:28:30
and 9.0, 8.0
| |
160 '2005': ('8.0',), | |
scottmg
2014/01/08 00:28:30
and 2005 through 2008e.
| |
161 '2005e': ('8.0',), | |
162 '2008': ('9.0',), | |
163 '2008e': ('9.0',), | |
164 '2010': ('10.0',), | |
165 '2010e': ('10.0',), | |
166 '2012': ('11.0',), | |
167 '2012e': ('11.0',), | |
168 '2013': ('12.0',), | |
169 '2013e': ('12.0',), | |
170 } | |
171 | |
172 requested_version = sys.argv[1] | |
173 vs_path = _DetectVisualStudioVersion(version_map[requested_version], | |
174 'e' in requested_version) | |
175 if not vs_path: | |
176 # No Visual Studio version detected. | |
177 print '""' # Return empty string to .gn file. | |
178 sys.exit(1); | |
179 | |
180 # Return Visual Studio path to the .gn file. | |
181 print '"%s"' % vs_path | |
OLD | NEW |