From 919a9b29d6af44289bdb85fbf6aef2e7a618d345 Mon Sep 17 00:00:00 2001 From: Refael Ackermann Date: Mon, 13 Feb 2017 16:29:56 -0500 Subject: [PATCH] Make `powershell` call version 2 compatible --- lib/find-vs2017.js | 34 +++++-- tools/Get-VS7.cs | 224 +++++++++++++++++++++++++++++++++++++++++ tools/Get-VSConfig.ps1 | 176 -------------------------------- 3 files changed, 252 insertions(+), 182 deletions(-) create mode 100644 tools/Get-VS7.cs delete mode 100644 tools/Get-VSConfig.ps1 diff --git a/lib/find-vs2017.js b/lib/find-vs2017.js index 55f2af113a..3ff4bf8194 100644 --- a/lib/find-vs2017.js +++ b/lib/find-vs2017.js @@ -10,11 +10,13 @@ var log = require('npmlog') var vs2017Setup -function tryVS7 (gyp) { +function tryVS7_COM (gyp) { if (vs2017Setup) return vs2017Setup; try { - const psFile = path.join(__dirname, '..', 'tools', 'Get-VSConfig.ps1'); - const vsSetupRaw = cp.execSync('powershell ' + psFile).toString(); + const csFile = path.join(__dirname, '..', 'tools', 'Get-VS7.cs'); + const cmd = 'powershell -ExecutionPolicy Unrestricted -Command ' + + '"&{ Add-Type -Path ' + csFile + '; [VisualStudioConfiguration.Program]::Main(@())}"' + const vsSetupRaw = cp.execSync(cmd).toString(); if (!vsSetupRaw) return; const vsSetup = vsSetupRaw.split(/[\r|\n]/g).reduce((s, l) => { const lParts = l.split(': '); @@ -27,12 +29,32 @@ function tryVS7 (gyp) { } } +function tryVS7_registry(gyp) { + const magicKey = String.raw`HKLM\Software\Microsoft\VisualStudio\SxS\VS7`; + const magicQuery = `reg query ${magicKey} /reg:32`; + const qRet = cp.execSync(magicQuery).toString().trim(); + if (qRet.includes('ERROR')) { + gyp.bindings.log('Couldn\'t find VS7 in registry:('); + return; + } + const values = qRet.split(/[\r|\n]+/g).slice(1); + const ret = values.map(v => { + const parts = v.trim().replace(/\s+/g, ' ').split(' '); + return [Number(parts[0]), parts[2]]; + }); + if (!ret.length) { + gyp.bindings.log('Couldn\'t find VS7 in registry'); + return; + } + const maxVer = Math.max.apply(Math, ret.map(v => v[0])); + return ret.find(v => v[0] === maxVer)[1]; +} function locateMsbuild(gyp, callback) { - var vsSetup = tryVS7(gyp) + const vsSetup = tryVS7_COM(gyp) || tryVS7_registry(gyp); if (!vsSetup)return callback() - var msbuild_location = path.join(vsSetup.InstallationPath, 'MSBuild', + const msbuild_location = path.join(vsSetup.InstallationPath, 'MSBuild', '15.0', 'Bin', 'MSBuild.exe') log.verbose('find vs2017', 'looking for msbuild in %s', msbuild_location) fs.access(msbuild_location, function(err) { @@ -42,7 +64,7 @@ function locateMsbuild(gyp, callback) { function setGypVS2017Env(gyp, callback) { - var vsSetup = tryVS7(gyp); + const vsSetup = tryVS7_COM(gyp) || tryVS7_registry(gyp); if (!vsSetup)return callback() gyp.opts.msvs_version = '2017'; diff --git a/tools/Get-VS7.cs b/tools/Get-VS7.cs new file mode 100644 index 0000000000..a4ca7ddb2e --- /dev/null +++ b/tools/Get-VS7.cs @@ -0,0 +1,224 @@ +// powershell -ExecutionPolicy Unrestricted -Version "2.0" -Command "&{ Add-Type -Path Program.cs; [VisualStudioConfiguration.Program]::Main(@())}" +using System; +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))] + [TypeLibImportClass(typeof(SetupConfigurationClass))] + [ComImport] + public interface SetupConfiguration : ISetupConfiguration2, ISetupConfiguration + { + } + + [Guid("177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D")] + [ClassInterface(ClassInterfaceType.None)] + [ComImport] + public class SetupConfigurationClass + { + } + + public static class Program + { + public static int Main(string[] args) + { + try + { + ISetupConfiguration query = new SetupConfiguration(); + ISetupConfiguration2 query2 = (ISetupConfiguration2) query; + IEnumSetupInstances e = query2.EnumAllInstances(); + ISetupInstance2[] rgelt = new ISetupInstance2[1]; + int pceltFetched; + do + { + e.Next(1, rgelt, out pceltFetched); + if (pceltFetched > 0) + PrintInstance(rgelt[0]); + } while (pceltFetched > 0); + return 0; + } + catch (Exception ex) + { + Console.Error.WriteLine("Error 0x{0:x8}: {1}", ex, ex.Message); + return 1; + } + } + + private static void PrintInstance(ISetupInstance2 setupInstance2) + { + Console.WriteLine("InstallationPath: {0}", setupInstance2.GetInstallationPath()); + Console.WriteLine("Product: {0}", setupInstance2.GetProduct().GetId()); + foreach (ISetupPackageReference package in setupInstance2.GetPackages()) + { + if (package.GetType() != "Exe") continue; + string id = package.GetId(); + if (id.IndexOf("SDK", StringComparison.Ordinal) == -1) continue; + string[] parts = id.Split('_'); + if (parts.Length < 2) continue; + string sdkVer = parts[1]; + char[] chars = {'1', '0', '8'}; + if (sdkVer.IndexOfAny(chars) == -1) continue; + Console.WriteLine("SDK: {0}", sdkVer); + } + Console.WriteLine(); + } + } +} \ No newline at end of file diff --git a/tools/Get-VSConfig.ps1 b/tools/Get-VSConfig.ps1 deleted file mode 100644 index 886f3cd95e..0000000000 --- a/tools/Get-VSConfig.ps1 +++ /dev/null @@ -1,176 +0,0 @@ -$Source = @" -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using Microsoft.VisualStudio.Setup.Configuration; - - -namespace Microsoft.VisualStudio.Setup.Configuration -{ - [CompilerGenerated] - [Flags] - [TypeIdentifier("310100ba-5f84-4103-abe0-e8132ae862d9", "Microsoft.VisualStudio.Setup.Configuration.InstanceState")] - [ComVisible(true)] - public enum InstanceState : uint - { - None = 0, - Local = 1, - Registered = 2, - NoRebootRequired = 4, - NoErrors = 8, - Complete = 4294967295 - } - - [CompilerGenerated] - [Guid("6380BCFF-41D3-4B2E-8B2E-BF8A6810C848")] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - [TypeIdentifier] - [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); - } - - - [CompilerGenerated] - [Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - [TypeIdentifier] - [ComImport] - public interface ISetupConfiguration - { - } - - [CompilerGenerated] - [Guid("26AAB78C-4A60-49D6-AF3B-3C35BC93365D")] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - [TypeIdentifier] - [ComImport] - public interface ISetupConfiguration2 : ISetupConfiguration - { - [SpecialName] - [MethodImpl(MethodCodeType = MethodCodeType.Runtime)] - void _VtblGap1_3(); - - [return: MarshalAs(UnmanagedType.Interface)] - IEnumSetupInstances EnumAllInstances(); - } - - - [CompilerGenerated] - [Guid("B41463C3-8866-43B5-BC33-2B0676F7F42E")] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - [TypeIdentifier] - [ComImport] - public interface ISetupInstance - { - [SpecialName] - [MethodImpl(MethodCodeType = MethodCodeType.Runtime)] - void _VtblGap1_4(); - - [return: MarshalAs(UnmanagedType.BStr)] - string GetInstallationVersion(); - } - - [CompilerGenerated] - [Guid("89143C9A-05AF-49B0-B717-72E218A2185C")] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - [TypeIdentifier] - [ComImport] - public interface ISetupInstance2 : ISetupInstance - { - [return: MarshalAs(UnmanagedType.BStr)] - string GetInstanceId(); - - [SpecialName] - [MethodImpl(MethodCodeType = MethodCodeType.Runtime)] - void _VtblGap1_2(); - - [return: MarshalAs(UnmanagedType.BStr)] - string GetInstallationPath(); - - [SpecialName] - [MethodImpl(MethodCodeType = MethodCodeType.Runtime)] - void _VtblGap2_4(); - - [return: MarshalAs(UnmanagedType.U4)] - InstanceState GetState(); - - [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)] - ISetupPackageReference[] GetPackages(); - - ISetupPackageReference GetProduct(); - } - - [CompilerGenerated] - [Guid("DA8D8A16-B2B6-4487-A2F1-594CCCCD6BF5")] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - [TypeIdentifier] - [ComImport] - public interface ISetupPackageReference - { - [return: MarshalAs(UnmanagedType.BStr)] - string GetId(); - - [SpecialName] - [MethodImpl(MethodCodeType = MethodCodeType.Runtime)] - void _VtblGap1_4(); - - [return: MarshalAs(UnmanagedType.BStr)] - string GetType(); - } -} - -public static class VisualStudioSetup -{ - public static int Main() - { - try - { - var query = - (ISetupConfiguration2) - Activator.CreateInstance(Marshal.GetTypeFromCLSID(new Guid("177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D"))); - var enumSetupInstances = query.EnumAllInstances(); - var rgelt = new ISetupInstance2[1]; - int pceltFetched; - do - { - // ISSUE: reference to a compiler-generated method - enumSetupInstances.Next(1, rgelt, out pceltFetched); - if (pceltFetched > 0) - PrintInstance(rgelt[0]); - } while (pceltFetched > 0); - return 0; - } - catch (Exception ex) - { - Console.Error.WriteLine("Error 0x{0:x8}: {1}", ex.HResult, ex.Message); - return ex.HResult; - } - } - - - private static void PrintInstance(ISetupInstance2 setupInstance2) - { - Console.WriteLine("InstallationPath: {0}", setupInstance2.GetInstallationPath()); - Console.WriteLine("Product: {0}", setupInstance2.GetProduct().GetId()); - foreach (var package in setupInstance2.GetPackages()) - { - if (package.GetType() != "Exe") continue;; - var id = package.GetId(); - if (id.IndexOf("SDK", StringComparison.Ordinal) == -1) continue; - var parts = id.Split('_'); - if (parts.Length < 2) continue; - var sdkVer = parts[1]; - char[] chars = { '1', '0', '8' }; - if (sdkVer.IndexOfAny(chars) == -1) continue; - Console.WriteLine("SDK: {0}", sdkVer); - } - Console.WriteLine(); - } -} -"@ -Add-Type -TypeDefinition $Source -Language CSharp -[VisualStudioSetup]::Main()