From 840499b504e03f780c622309f0d9d535240bdb0a Mon Sep 17 00:00:00 2001 From: Alexei Lozovsky Date: Sat, 3 Oct 2020 17:51:55 +0300 Subject: [PATCH] Avoid slow "vswhere" calls (#14) Recently added Visual Studio location with "vswhere" seems to be very slow when using "-find" with path patterns. As in, 5 minutes slow. vswhere does not provide much insight into why this happens, but I guess that's because filesystem operations (and search in particular) are not very fast on Windows. Improve the search performance by combining vswhere with probing. Use vswhere to locate the installation root, and then probe around for the batch script we need. Also, don't use vswhere for Visual Studio 2015 as it does not seem to work. Rely only on probing here. And also, add some debug logs so that it's possible to track which path has been used, if you're interested in it. --- index.js | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/index.js b/index.js index fd128fa..3ea5393 100644 --- a/index.js +++ b/index.js @@ -20,44 +20,43 @@ const InterestingVariables = [ ] function findWithVswhere(pattern) { - let path = null; try { - path = child_process.execSync(`vswhere -products * -latest -prerelease -find ${pattern}`).toString().trim() + let installationPath = child_process.execSync(`vswhere -products * -latest -prerelease -property installationPath`).toString().trim() + return installationPath + '\\' + pattern } catch (e) { - console.log(e) + core.warn(`vswhere failed: ${e}`) } - return path + return null } function findVcvarsall() { - // use vswhere - let path = findWithVswhere('**/Auxiliary/Build/vcvarsall.bat') + // If vswhere is available, ask it about the location of the latest Visual Studio. + let path = findWithVswhere('VC\\Auxiliary\\Build\\vcvarsall.bat') if (path && fs.existsSync(path)) { + core.debug(`found with vswhere: ${path}`) return path } + // If that does not work, try the standard installation locations, + // starting with the latest and moving to the oldest. const programFiles = process.env['ProgramFiles(x86)'] - // Given the order of each list it should check - // for the more recent versions first and the - // highest grade edition first. for (const ver of VERSIONS) { for (const ed of EDITIONS) { path = `${programFiles}\\Microsoft Visual Studio\\${ver}\\${ed}\\VC\\Auxiliary\\Build\\vcvarsall.bat` if (fs.existsSync(path)) { + core.debug(`found standard location: ${path}`) return path } } } + // Special case for Visual Studio 2015 (and maybe earlier), try it out too. - // us vswhere - path = findWithVswhere('**/vcbuildtools.bat') - if (path && fs.existsSync(path)) { - return path - } path = `${programFiles}\\Microsoft Visual C++ Build Tools\\vcbuildtools.bat` if (fs.existsSync(path)) { + core.debug(`found VS 2015: ${path}`) return path } + throw new Error('Microsoft Visual Studio not found') }