@@ -224,35 +224,63 @@ def find_vswhere():
224
224
225
225
226
226
def find_vs_path (path , msvc_version ):
227
+ """
228
+ Attempts to find 'path' by invoking vswhere to identify where the
229
+ given msvc_version is installed.
230
+
231
+ vswhere is akin to things like 'pkg-config', it's an executable
232
+ that can be invoked to retrieve parameters of visual studio code
233
+ installations on the host machine.
234
+ """
227
235
vswhere = find_vswhere ()
228
236
237
+ # vswhere uses a math-like range expression for specifying the
238
+ # major release numbers.
239
+ # 16 = Visual Studio 2019,
240
+ # 17 = Visual Studio 2022,
229
241
if msvc_version == "2019" :
230
242
version = "[16,17)"
231
243
elif msvc_version == "2022" :
232
244
version = "[17,18)"
233
245
else :
234
246
raise ValueError (f"unsupported Visual Studio version: { msvc_version } " )
235
247
236
- p = subprocess .check_output (
237
- [
238
- str (vswhere ),
239
- # Visual Studio 2019.
240
- "-version" ,
241
- version ,
242
- "-property" ,
243
- "installationPath" ,
244
- "-products" ,
245
- "*" ,
246
- ]
247
- )
248
+ # Assemble the command line into an argv list for a subprocess
249
+ # call, so if the command fails we can tell the user what command
250
+ # we tried and enable them to potentially investigate further.
251
+ cmdline = [
252
+ str (vswhere ),
253
+ "-version" ,
254
+ version ,
255
+ "-property" ,
256
+ "installationPath" ,
257
+ "-prerelease" ,
258
+ "-products" ,
259
+ "*" ,
260
+ ]
261
+ p = subprocess .check_output (cmdline )
262
+ if not p :
263
+ # add quotes around any of the terms with spaces in them, so that
264
+ # the user can copy-and-paste the command.
265
+ cmdline = ['"%s"' % term if " " in term else term for term in cmdline ]
266
+ print ("could not find visual studio (using '%s')" % cmdline )
267
+ sys .exit (1 )
248
268
249
269
# Strictly speaking the output may not be UTF-8.
250
- p = pathlib .Path (p .strip ().decode ("utf-8" ))
251
-
252
- p = p / path
270
+ p = p .strip ().decode ("utf-8" )
271
+
272
+ # vswhere can potentially report multiple installed versions,
273
+ # one per line. The above 'strip' will have removed any
274
+ # trailing newlines, so if there is still a newline, there
275
+ # is more than one option.
276
+ if "\n " in p : # more than one line
277
+ print ("found multiple matching instances of visual studio %s:" % msvc_version )
278
+ print (p )
279
+ sys .exit (1 )
253
280
281
+ p = pathlib .Path (p , path )
254
282
if not p .exists ():
255
- print ("%s does not exist" % p )
283
+ print ("%s does not exist for vs%s " % ( p , msvc_version ) )
256
284
sys .exit (1 )
257
285
258
286
return p
0 commit comments