@@ -56,43 +56,43 @@ def _find_vc2015():
5656 return best_version , best_dir
5757
5858def _find_vc2017 ():
59- import _distutils_findvs
60- import threading
59+ """Returns "15, path" based on the result of invoking vswhere.exe
60+ If no install is found, returns "None, None"
6161
62- best_version = 0 , # tuple for full version comparisons
63- best_dir = None
62+ The version is returned to avoid unnecessarily changing the function
63+ result. It may be ignored when the path is not None.
64+
65+ If vswhere.exe is not available, by definition, VS 2017 is not
66+ installed.
67+ """
68+ import json
69+
70+ root = os .environ .get ("ProgramFiles(x86)" ) or os .environ .get ("ProgramFiles" )
71+ if not root :
72+ return None , None
6473
65- # We need to call findall() on its own thread because it will
66- # initialize COM.
67- all_packages = []
68- def _getall ():
69- all_packages .extend (_distutils_findvs .findall ())
70- t = threading .Thread (target = _getall )
71- t .start ()
72- t .join ()
73-
74- for name , version_str , path , packages in all_packages :
75- if 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64' in packages :
76- vc_dir = os .path .join (path , 'VC' , 'Auxiliary' , 'Build' )
77- if not os .path .isdir (vc_dir ):
78- continue
79- try :
80- version = tuple (int (i ) for i in version_str .split ('.' ))
81- except (ValueError , TypeError ):
82- continue
83- if version > best_version :
84- best_version , best_dir = version , vc_dir
8574 try :
86- best_version = best_version [0 ]
87- except IndexError :
88- best_version = None
89- return best_version , best_dir
75+ path = subprocess .check_output ([
76+ os .path .join (root , "Microsoft Visual Studio" , "Installer" , "vswhere.exe" ),
77+ "-latest" ,
78+ "-prerelease" ,
79+ "-requires" , "Microsoft.VisualStudio.Component.VC.Tools.x86.x64" ,
80+ "-property" , "installationPath" ,
81+ ], encoding = "mbcs" , errors = "strict" ).strip ()
82+ except (subprocess .CalledProcessError , OSError , UnicodeDecodeError ):
83+ return None , None
84+
85+ path = os .path .join (path , "VC" , "Auxiliary" , "Build" )
86+ if os .path .isdir (path ):
87+ return 15 , path
88+
89+ return None , None
9090
9191def _find_vcvarsall (plat_spec ):
92- best_version , best_dir = _find_vc2017 ()
92+ _ , best_dir = _find_vc2017 ()
9393 vcruntime = None
9494 vcruntime_plat = 'x64' if 'amd64' in plat_spec else 'x86'
95- if best_version :
95+ if best_dir :
9696 vcredist = os .path .join (best_dir , ".." , ".." , "redist" , "MSVC" , "**" ,
9797 "Microsoft.VC141.CRT" , "vcruntime140.dll" )
9898 try :
@@ -101,13 +101,13 @@ def _find_vcvarsall(plat_spec):
101101 except (ImportError , OSError , LookupError ):
102102 vcruntime = None
103103
104- if not best_version :
104+ if not best_dir :
105105 best_version , best_dir = _find_vc2015 ()
106106 if best_version :
107107 vcruntime = os .path .join (best_dir , 'redist' , vcruntime_plat ,
108108 "Microsoft.VC140.CRT" , "vcruntime140.dll" )
109109
110- if not best_version :
110+ if not best_dir :
111111 log .debug ("No suitable Visual C++ version found" )
112112 return None , None
113113
0 commit comments