From 1f79c98aebd861f71881815fb39510ff890cfd22 Mon Sep 17 00:00:00 2001 From: Refael Ackermann Date: Mon, 20 Feb 2017 19:16:24 -0500 Subject: [PATCH 1/9] win: find and setup for VS2017 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-By: João Reis --- lib/Find-VS2017.cs | 262 +++++++++++++++++++++++++++++++++++++++++++++ lib/build.js | 11 +- lib/configure.js | 20 +++- lib/find-vs2017.js | 47 ++++++++ 4 files changed, 336 insertions(+), 4 deletions(-) create mode 100644 lib/Find-VS2017.cs create mode 100644 lib/find-vs2017.js diff --git a/lib/Find-VS2017.cs b/lib/Find-VS2017.cs new file mode 100644 index 0000000000..fe0d1e08e1 --- /dev/null +++ b/lib/Find-VS2017.cs @@ -0,0 +1,262 @@ +// powershell -ExecutionPolicy Unrestricted -Version "2.0" -Command "&{Add-Type -Path Find-VS2017.cs; [VisualStudioConfiguration.Main]::Query()}" +using System; +using System.Text; +using System.Runtime.InteropServices; + +namespace VisualStudioConfiguration +{ + [Flags] + public enum InstanceState : uint + { + None = 0, + Local = 1, + Registered = 2, + NoRebootRequired = 4, + NoErrors = 8, + Complete = 4294967295, + } + + [Guid("6380BCFF-41D3-4B2E-8B2E-BF8A6810C848")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + public interface IEnumSetupInstances + { + + void Next([MarshalAs(UnmanagedType.U4), In] int celt, + [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface), Out] ISetupInstance[] rgelt, + [MarshalAs(UnmanagedType.U4)] out int pceltFetched); + + void Skip([MarshalAs(UnmanagedType.U4), In] int celt); + + void Reset(); + + [return: MarshalAs(UnmanagedType.Interface)] + IEnumSetupInstances Clone(); + } + + [Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + public interface ISetupConfiguration + { + } + + [Guid("26AAB78C-4A60-49D6-AF3B-3C35BC93365D")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + public interface ISetupConfiguration2 : ISetupConfiguration + { + + [return: MarshalAs(UnmanagedType.Interface)] + IEnumSetupInstances EnumInstances(); + + [return: MarshalAs(UnmanagedType.Interface)] + ISetupInstance GetInstanceForCurrentProcess(); + + [return: MarshalAs(UnmanagedType.Interface)] + ISetupInstance GetInstanceForPath([MarshalAs(UnmanagedType.LPWStr), In] string path); + + [return: MarshalAs(UnmanagedType.Interface)] + IEnumSetupInstances EnumAllInstances(); + } + + [Guid("B41463C3-8866-43B5-BC33-2B0676F7F42E")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + public interface ISetupInstance + { + } + + [Guid("89143C9A-05AF-49B0-B717-72E218A2185C")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + public interface ISetupInstance2 : ISetupInstance + { + [return: MarshalAs(UnmanagedType.BStr)] + string GetInstanceId(); + + [return: MarshalAs(UnmanagedType.Struct)] + System.Runtime.InteropServices.ComTypes.FILETIME GetInstallDate(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetInstallationName(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetInstallationPath(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetInstallationVersion(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetDisplayName([MarshalAs(UnmanagedType.U4), In] int lcid); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetDescription([MarshalAs(UnmanagedType.U4), In] int lcid); + + [return: MarshalAs(UnmanagedType.BStr)] + string ResolvePath([MarshalAs(UnmanagedType.LPWStr), In] string pwszRelativePath); + + [return: MarshalAs(UnmanagedType.U4)] + InstanceState GetState(); + + [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)] + ISetupPackageReference[] GetPackages(); + + ISetupPackageReference GetProduct(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetProductPath(); + + [return: MarshalAs(UnmanagedType.VariantBool)] + bool IsLaunchable(); + + [return: MarshalAs(UnmanagedType.VariantBool)] + bool IsComplete(); + + ISetupPropertyStore GetProperties(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetEnginePath(); + } + + [Guid("DA8D8A16-B2B6-4487-A2F1-594CCCCD6BF5")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + public interface ISetupPackageReference + { + + [return: MarshalAs(UnmanagedType.BStr)] + string GetId(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetVersion(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetChip(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetLanguage(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetBranch(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetType(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetUniqueId(); + + [return: MarshalAs(UnmanagedType.VariantBool)] + bool GetIsExtension(); + } + + [Guid("c601c175-a3be-44bc-91f6-4568d230fc83")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + public interface ISetupPropertyStore + { + + [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] + string[] GetNames(); + + object GetValue([MarshalAs(UnmanagedType.LPWStr), In] string pwszName); + } + + [Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")] + [CoClass(typeof(SetupConfigurationClass))] + [ComImport] + public interface SetupConfiguration : ISetupConfiguration2, ISetupConfiguration + { + } + + [Guid("177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D")] + [ClassInterface(ClassInterfaceType.None)] + [ComImport] + public class SetupConfigurationClass + { + } + + public static class Main + { + public static void Query() + { + ISetupConfiguration query = new SetupConfiguration(); + ISetupConfiguration2 query2 = (ISetupConfiguration2)query; + IEnumSetupInstances e = query2.EnumAllInstances(); + + int pceltFetched; + ISetupInstance2[] rgelt = new ISetupInstance2[1]; + StringBuilder log = new StringBuilder(); + while (true) + { + e.Next(1, rgelt, out pceltFetched); + if (pceltFetched <= 0) + { + Console.WriteLine(String.Format("{{\"log\":\"{0}\"}}", log.ToString())); + return; + } + if (CheckInstance(rgelt[0], ref log)) + return; + } + } + + private static bool CheckInstance(ISetupInstance2 setupInstance2, ref StringBuilder log) + { + // Visual Studio Community 2017 component directory: + // https://www.visualstudio.com/en-us/productinfo/vs2017-install-product-Community.workloads + + string path = setupInstance2.GetInstallationPath().Replace("\\", "\\\\"); + log.Append(String.Format("Found installation at: {0}\\n", path)); + + bool hasMSBuild = false; + bool hasVCTools = false; + uint Win10SDKVer = 0; + bool hasWin8SDK = false; + + foreach (ISetupPackageReference package in setupInstance2.GetPackages()) + { + const string Win10SDKPrefix = "Microsoft.VisualStudio.Component.Windows10SDK."; + + string id = package.GetId(); + if (id == "Microsoft.Component.MSBuild") + hasMSBuild = true; + else if (id == "Microsoft.VisualStudio.Component.VC.Tools.x86.x64") + hasVCTools = true; + else if (id.StartsWith(Win10SDKPrefix)) + Win10SDKVer = Math.Max(Win10SDKVer, UInt32.Parse(id.Substring(Win10SDKPrefix.Length))); + else if (id == "Microsoft.VisualStudio.Component.Windows81SDK") + hasWin8SDK = true; + else + continue; + + log.Append(String.Format(" - Found {0}\\n", id)); + } + + if (!hasMSBuild) + log.Append(" - Missing MSBuild (Microsoft.Component.MSBuild)\\n"); + if (!hasVCTools) + log.Append(" - Missing VC++ 2017 v141 toolset (x86,x64) (Microsoft.VisualStudio.Component.VC.Tools.x86.x64)\\n"); + if ((Win10SDKVer == 0) && (!hasWin8SDK)) + log.Append(" - Missing a Windows SDK (Microsoft.VisualStudio.Component.Windows10SDK.* or Microsoft.VisualStudio.Component.Windows81SDK)\\n"); + + if (hasMSBuild && hasVCTools) + { + if (Win10SDKVer > 0) + { + log.Append(" - Using this installation with Windows 10 SDK"/*\\n*/); + Console.WriteLine(String.Format("{{\"log\":\"{0}\",\"path\":\"{1}\",\"sdk\":\"10.0.{2}.0\"}}", log.ToString(), path, Win10SDKVer)); + return true; + } + else if (hasWin8SDK) + { + log.Append(" - Using this installation with Windows 8.1 SDK"/*\\n*/); + Console.WriteLine(String.Format("{{\"log\":\"{0}\",\"path\":\"{1}\",\"sdk\":\"8.1\"}}", log.ToString(), path)); + return true; + } + } + + log.Append(" - Some required components are missing, not using this installation\\n"); + return false; + } + } +} diff --git a/lib/build.js b/lib/build.js index 0374fbc810..af71795532 100644 --- a/lib/build.js +++ b/lib/build.js @@ -14,7 +14,9 @@ var fs = require('graceful-fs') , mkdirp = require('mkdirp') , exec = require('child_process').exec , processRelease = require('./process-release') - , win = process.platform == 'win32' + , win = process.platform === 'win32' +if (win) + var findVS2017 = require('./find-vs2017') exports.usage = 'Invokes `' + (win ? 'msbuild' : 'make') + '` and builds the module' @@ -124,6 +126,13 @@ function build (gyp, argv, callback) { */ function findMsbuild () { + if (config.variables.msbuild_path) { + command = config.variables.msbuild_path + log.verbose('using MSBuild:', command) + copyNodeLib() + return + } + log.verbose('could not find "msbuild.exe" in PATH - finding location in registry') var notfoundErr = 'Can\'t find "msbuild.exe". Do you have Microsoft Visual Studio C++ 2008+ installed?' var cmd = 'reg query "HKLM\\Software\\Microsoft\\MSBuild\\ToolsVersions" /s' diff --git a/lib/configure.js b/lib/configure.js index d52b2902b0..c2fb86cba1 100644 --- a/lib/configure.js +++ b/lib/configure.js @@ -19,9 +19,11 @@ var fs = require('graceful-fs') , cp = require('child_process') , extend = require('util')._extend , processRelease = require('./process-release') - , win = process.platform == 'win32' + , win = process.platform === 'win32' , findNodeDirectory = require('./find-node-directory') , msgFormat = require('util').format +if (win) + var findVS2017 = require('./find-vs2017') exports.usage = 'Generates ' + (win ? 'MSVC project files' : 'a Makefile') + ' for the current module' @@ -137,6 +139,18 @@ function configure (gyp, argv, callback) { // disable -T "thin" static archives by default variables.standalone_static_library = gyp.opts.thin ? 0 : 1 + if (win && !(gyp.opts.msvs_version && gyp.opts.msvs_version !== '2017')) { + const vsSetup = findVS2017() + if (vsSetup) { + gyp.opts.msvs_version = '2015' + process.env['GYP_MSVS_VERSION'] = 2015 + process.env['GYP_MSVS_OVERRIDE_PATH'] = vsSetup.path + defaults['msbuild_toolset'] = 'v141' + defaults['msvs_windows_target_platform_version'] = vsSetup.sdk + variables['msbuild_path'] = path.join(vsSetup.path, 'MSBuild', '15.0', 'Bin', 'MSBuild.exe') + } + } + // loop through the rest of the opts and add the unknown ones as variables. // this allows for module-specific configure flags like: // @@ -317,9 +331,9 @@ function configure (gyp, argv, callback) { } /** - * Returns the first file or directory from an array of candidates that is + * Returns the first file or directory from an array of candidates that is * readable by the current user, or undefined if none of the candidates are - * readable. + * readable. */ function findAccessibleSync (logprefix, dir, candidates) { for (var next = 0; next < candidates.length; next++) { diff --git a/lib/find-vs2017.js b/lib/find-vs2017.js new file mode 100644 index 0000000000..915cb9283b --- /dev/null +++ b/lib/find-vs2017.js @@ -0,0 +1,47 @@ +const log = require('npmlog') + , execSync = require('child_process').execSync + , path = require('path') + +var hasCache = false + , cache = null + +function findVS2017() { + if (hasCache) + return cache + + hasCache = true + + const ps = 'PowerShell -ExecutionPolicy Unrestricted -Command ' + const csFile = path.join(__dirname, 'Find-VS2017.cs') + const psQuery = ps + '"&{Add-Type -Path \'' + csFile + '\'; [VisualStudioConfiguration.Main]::Query()}" 2>&1' + + var vsSetup + try { + const vsSetupRaw = execSync(psQuery, { encoding: 'utf8' }) + log.silly('find vs2017', 'vsSetupRaw:', vsSetupRaw) + vsSetup = JSON.parse(vsSetupRaw) + log.silly('find vs2017', 'vsSetup:', vsSetup) + } catch (e) { + log.silly('find vs2017', e) + log.verbose('find vs2017', 'could not use PowerShell to find VS2017') + return cache + } + + if (vsSetup && vsSetup.log) + log.verbose('find vs2017', vsSetup.log.trimRight()) + + if (!vsSetup || !vsSetup.path || !vsSetup.sdk) { + log.verbose('find vs2017', 'no usable installation found') + return cache + } + + cache = { + "path": vsSetup.path, + "sdk": vsSetup.sdk + } + + log.verbose('find vs2017', 'using installation:', cache.path) + return cache +} + +module.exports = findVS2017 From 2dd811b3595c2002ffd924384c4accd85e6dc34a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Reis?= Date: Tue, 28 Feb 2017 12:58:43 +0000 Subject: [PATCH 2/9] fixup: unnecessary require --- lib/build.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/build.js b/lib/build.js index af71795532..5253109857 100644 --- a/lib/build.js +++ b/lib/build.js @@ -15,8 +15,6 @@ var fs = require('graceful-fs') , exec = require('child_process').exec , processRelease = require('./process-release') , win = process.platform === 'win32' -if (win) - var findVS2017 = require('./find-vs2017') exports.usage = 'Invokes `' + (win ? 'msbuild' : 'make') + '` and builds the module' From 034a33078ce30007b74ec7b94156d4270b67e1c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Reis?= Date: Wed, 8 Mar 2017 18:10:11 +0000 Subject: [PATCH 3/9] fixup: change MSBuild dependency --- lib/Find-VS2017.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Find-VS2017.cs b/lib/Find-VS2017.cs index fe0d1e08e1..7c3a67c474 100644 --- a/lib/Find-VS2017.cs +++ b/lib/Find-VS2017.cs @@ -218,7 +218,7 @@ private static bool CheckInstance(ISetupInstance2 setupInstance2, ref StringBuil const string Win10SDKPrefix = "Microsoft.VisualStudio.Component.Windows10SDK."; string id = package.GetId(); - if (id == "Microsoft.Component.MSBuild") + if (id == "Microsoft.VisualStudio.VC.MSBuild.Base") hasMSBuild = true; else if (id == "Microsoft.VisualStudio.Component.VC.Tools.x86.x64") hasVCTools = true; @@ -233,7 +233,7 @@ private static bool CheckInstance(ISetupInstance2 setupInstance2, ref StringBuil } if (!hasMSBuild) - log.Append(" - Missing MSBuild (Microsoft.Component.MSBuild)\\n"); + log.Append(" - Missing Visual Studio C++ core features (Microsoft.VisualStudio.VC.MSBuild.Base)\\n"); if (!hasVCTools) log.Append(" - Missing VC++ 2017 v141 toolset (x86,x64) (Microsoft.VisualStudio.Component.VC.Tools.x86.x64)\\n"); if ((Win10SDKVer == 0) && (!hasWin8SDK)) From 5a06befb972c462cad62ec403ed762f8bcbdc159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Reis?= Date: Tue, 14 Mar 2017 11:00:49 +0000 Subject: [PATCH 4/9] fixup: s/const/var --- lib/configure.js | 2 +- lib/find-vs2017.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/configure.js b/lib/configure.js index c2fb86cba1..ba76921a4e 100644 --- a/lib/configure.js +++ b/lib/configure.js @@ -140,7 +140,7 @@ function configure (gyp, argv, callback) { variables.standalone_static_library = gyp.opts.thin ? 0 : 1 if (win && !(gyp.opts.msvs_version && gyp.opts.msvs_version !== '2017')) { - const vsSetup = findVS2017() + var vsSetup = findVS2017() if (vsSetup) { gyp.opts.msvs_version = '2015' process.env['GYP_MSVS_VERSION'] = 2015 diff --git a/lib/find-vs2017.js b/lib/find-vs2017.js index 915cb9283b..09d9711798 100644 --- a/lib/find-vs2017.js +++ b/lib/find-vs2017.js @@ -1,4 +1,4 @@ -const log = require('npmlog') +var log = require('npmlog') , execSync = require('child_process').execSync , path = require('path') @@ -11,13 +11,13 @@ function findVS2017() { hasCache = true - const ps = 'PowerShell -ExecutionPolicy Unrestricted -Command ' - const csFile = path.join(__dirname, 'Find-VS2017.cs') - const psQuery = ps + '"&{Add-Type -Path \'' + csFile + '\'; [VisualStudioConfiguration.Main]::Query()}" 2>&1' + var ps = 'PowerShell -ExecutionPolicy Unrestricted -Command ' + var csFile = path.join(__dirname, 'Find-VS2017.cs') + var psQuery = ps + '"&{Add-Type -Path \'' + csFile + '\'; [VisualStudioConfiguration.Main]::Query()}" 2>&1' var vsSetup try { - const vsSetupRaw = execSync(psQuery, { encoding: 'utf8' }) + var vsSetupRaw = execSync(psQuery, { encoding: 'utf8' }) log.silly('find vs2017', 'vsSetupRaw:', vsSetupRaw) vsSetup = JSON.parse(vsSetupRaw) log.silly('find vs2017', 'vsSetup:', vsSetup) From 5faa4887bacd0ff38d256e93393a04423a71af43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Reis?= Date: Tue, 14 Mar 2017 11:03:28 +0000 Subject: [PATCH 5/9] fixup: De Morgan --- lib/configure.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/configure.js b/lib/configure.js index ba76921a4e..1f6c397ec2 100644 --- a/lib/configure.js +++ b/lib/configure.js @@ -139,7 +139,7 @@ function configure (gyp, argv, callback) { // disable -T "thin" static archives by default variables.standalone_static_library = gyp.opts.thin ? 0 : 1 - if (win && !(gyp.opts.msvs_version && gyp.opts.msvs_version !== '2017')) { + if (win && (!gyp.opts.msvs_version || gyp.opts.msvs_version === '2017')) { var vsSetup = findVS2017() if (vsSetup) { gyp.opts.msvs_version = '2015' From e1cc9ec528938a5d3c40cb798e52e8858560799f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Reis?= Date: Tue, 14 Mar 2017 11:30:45 +0000 Subject: [PATCH 6/9] fixup: comment --- lib/configure.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/configure.js b/lib/configure.js index 1f6c397ec2..a33105ef8c 100644 --- a/lib/configure.js +++ b/lib/configure.js @@ -142,6 +142,9 @@ function configure (gyp, argv, callback) { if (win && (!gyp.opts.msvs_version || gyp.opts.msvs_version === '2017')) { var vsSetup = findVS2017() if (vsSetup) { + // GYP doesn't (yet) have support for VS2017, so we force it to VS2015 + // to avoid pulling a floating patch that has not landed upstream. + // Ref: https://chromium-review.googlesource.com/#/c/433540/ gyp.opts.msvs_version = '2015' process.env['GYP_MSVS_VERSION'] = 2015 process.env['GYP_MSVS_OVERRIDE_PATH'] = vsSetup.path From 4860d7262498341ef7b19a30ebc9ece57b769921 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Reis?= Date: Tue, 14 Mar 2017 15:25:31 +0000 Subject: [PATCH 7/9] fixup: async, v0.10 compatible (using execFile) --- lib/configure.js | 39 +++++++++++++++---------- lib/find-vs2017.js | 73 +++++++++++++++++++++++----------------------- 2 files changed, 60 insertions(+), 52 deletions(-) diff --git a/lib/configure.js b/lib/configure.js index a33105ef8c..3349e9fedf 100644 --- a/lib/configure.js +++ b/lib/configure.js @@ -88,11 +88,22 @@ function configure (gyp, argv, callback) { mkdirp(buildDir, function (err, isNew) { if (err) return callback(err) log.verbose('build dir', '"build" dir needed to be created?', isNew) - createConfigFile() + if (win && (!gyp.opts.msvs_version || gyp.opts.msvs_version === '2017')) { + findVS2017(function (err, vsSetup) { + if (err) { + log.verbose('Not using VS2017:', err.message) + createConfigFile() + } else { + createConfigFile(null, vsSetup) + } + }) + } else { + createConfigFile() + } }) } - function createConfigFile (err) { + function createConfigFile (err, vsSetup) { if (err) return callback(err) var configFilename = 'config.gypi' @@ -139,19 +150,17 @@ function configure (gyp, argv, callback) { // disable -T "thin" static archives by default variables.standalone_static_library = gyp.opts.thin ? 0 : 1 - if (win && (!gyp.opts.msvs_version || gyp.opts.msvs_version === '2017')) { - var vsSetup = findVS2017() - if (vsSetup) { - // GYP doesn't (yet) have support for VS2017, so we force it to VS2015 - // to avoid pulling a floating patch that has not landed upstream. - // Ref: https://chromium-review.googlesource.com/#/c/433540/ - gyp.opts.msvs_version = '2015' - process.env['GYP_MSVS_VERSION'] = 2015 - process.env['GYP_MSVS_OVERRIDE_PATH'] = vsSetup.path - defaults['msbuild_toolset'] = 'v141' - defaults['msvs_windows_target_platform_version'] = vsSetup.sdk - variables['msbuild_path'] = path.join(vsSetup.path, 'MSBuild', '15.0', 'Bin', 'MSBuild.exe') - } + if (vsSetup) { + // GYP doesn't (yet) have support for VS2017, so we force it to VS2015 + // to avoid pulling a floating patch that has not landed upstream. + // Ref: https://chromium-review.googlesource.com/#/c/433540/ + gyp.opts.msvs_version = '2015' + process.env['GYP_MSVS_VERSION'] = 2015 + process.env['GYP_MSVS_OVERRIDE_PATH'] = vsSetup.path + defaults['msbuild_toolset'] = 'v141' + defaults['msvs_windows_target_platform_version'] = vsSetup.sdk + variables['msbuild_path'] = path.join(vsSetup.path, 'MSBuild', '15.0', + 'Bin', 'MSBuild.exe') } // loop through the rest of the opts and add the unknown ones as variables. diff --git a/lib/find-vs2017.js b/lib/find-vs2017.js index 09d9711798..8c79e9ec9b 100644 --- a/lib/find-vs2017.js +++ b/lib/find-vs2017.js @@ -1,47 +1,46 @@ var log = require('npmlog') - , execSync = require('child_process').execSync + , execFile = require('child_process').execFile , path = require('path') -var hasCache = false - , cache = null +function findVS2017(callback) { + var ps = path.join(process.env.SystemRoot, 'System32', 'WindowsPowerShell', + 'v1.0', 'powershell.exe') + var csFile = path.join(__dirname, 'Find-VS2017.cs') + var psArgs = ['-ExecutionPolicy', 'Unrestricted', '-Command', + '&{Add-Type -Path \'' + csFile + + '\'; [VisualStudioConfiguration.Main]::Query()}'] + + log.silly('find vs2017', 'Running', ps, psArgs) + var child = execFile(ps, psArgs, { encoding: 'utf8' }, + function (err, stdout, stderr) { + log.silly('find vs2017', 'PS err:', err) + log.silly('find vs2017', 'PS stdout:', stdout) + log.silly('find vs2017', 'PS stderr:', stderr) + + if (err) + return callback(new Error('Could not use PowerShell to find VS2017')) + + var vsSetup + try { + vsSetup = JSON.parse(stdout) + } catch (e) { + log.silly('find vs2017', e) + return callback(new Error('Could not use PowerShell to find VS2017')) + } + log.silly('find vs2017', 'vsSetup:', vsSetup) -function findVS2017() { - if (hasCache) - return cache + if (vsSetup && vsSetup.log) + log.verbose('find vs2017', vsSetup.log.trimRight()) - hasCache = true + if (!vsSetup || !vsSetup.path || !vsSetup.sdk) { + return callback(new Error('No usable installation of VS2017 found')) + } - var ps = 'PowerShell -ExecutionPolicy Unrestricted -Command ' - var csFile = path.join(__dirname, 'Find-VS2017.cs') - var psQuery = ps + '"&{Add-Type -Path \'' + csFile + '\'; [VisualStudioConfiguration.Main]::Query()}" 2>&1' + log.verbose('find vs2017', 'using installation:', vsSetup.path) + callback(null, { "path": vsSetup.path, "sdk": vsSetup.sdk }) + }) - var vsSetup - try { - var vsSetupRaw = execSync(psQuery, { encoding: 'utf8' }) - log.silly('find vs2017', 'vsSetupRaw:', vsSetupRaw) - vsSetup = JSON.parse(vsSetupRaw) - log.silly('find vs2017', 'vsSetup:', vsSetup) - } catch (e) { - log.silly('find vs2017', e) - log.verbose('find vs2017', 'could not use PowerShell to find VS2017') - return cache - } - - if (vsSetup && vsSetup.log) - log.verbose('find vs2017', vsSetup.log.trimRight()) - - if (!vsSetup || !vsSetup.path || !vsSetup.sdk) { - log.verbose('find vs2017', 'no usable installation found') - return cache - } - - cache = { - "path": vsSetup.path, - "sdk": vsSetup.sdk - } - - log.verbose('find vs2017', 'using installation:', cache.path) - return cache + child.stdin.end() } module.exports = findVS2017 From e353a285a74ee7848f9446e21b1fe6c4f6c228f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Reis?= Date: Tue, 14 Mar 2017 19:22:07 +0000 Subject: [PATCH 8/9] fixup: attribution --- lib/Find-VS2017.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/Find-VS2017.cs b/lib/Find-VS2017.cs index 7c3a67c474..8f69cfa432 100644 --- a/lib/Find-VS2017.cs +++ b/lib/Find-VS2017.cs @@ -1,3 +1,6 @@ +// Copyright 2017 - Refael Ackermann +// Distributed under MIT style license +// See accompanying file LICENSE at https://github.com/node4good/windows-autoconf // powershell -ExecutionPolicy Unrestricted -Version "2.0" -Command "&{Add-Type -Path Find-VS2017.cs; [VisualStudioConfiguration.Main]::Query()}" using System; using System.Text; From 4d0b91fb92593c6eecd474f91052ae36902d7862 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Reis?= Date: Tue, 14 Mar 2017 19:45:48 +0000 Subject: [PATCH 9/9] fixup: Find-VS2017.cs API update --- lib/Find-VS2017.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/Find-VS2017.cs b/lib/Find-VS2017.cs index 8f69cfa432..a41a354f61 100644 --- a/lib/Find-VS2017.cs +++ b/lib/Find-VS2017.cs @@ -1,6 +1,8 @@ // Copyright 2017 - Refael Ackermann // Distributed under MIT style license // See accompanying file LICENSE at https://github.com/node4good/windows-autoconf + +// Usage: // powershell -ExecutionPolicy Unrestricted -Version "2.0" -Command "&{Add-Type -Path Find-VS2017.cs; [VisualStudioConfiguration.Main]::Query()}" using System; using System.Text; @@ -116,6 +118,7 @@ public interface ISetupInstance2 : ISetupInstance [return: MarshalAs(UnmanagedType.VariantBool)] bool IsComplete(); + [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)] ISetupPropertyStore GetProperties(); [return: MarshalAs(UnmanagedType.BStr)]