Skip to content

Commit 919a9b2

Browse files
committed
Make powershell call version 2 compatible
1 parent bde0a30 commit 919a9b2

File tree

3 files changed

+252
-182
lines changed

3 files changed

+252
-182
lines changed

lib/find-vs2017.js

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ var log = require('npmlog')
1010

1111
var vs2017Setup
1212

13-
function tryVS7 (gyp) {
13+
function tryVS7_COM (gyp) {
1414
if (vs2017Setup) return vs2017Setup;
1515
try {
16-
const psFile = path.join(__dirname, '..', 'tools', 'Get-VSConfig.ps1');
17-
const vsSetupRaw = cp.execSync('powershell ' + psFile).toString();
16+
const csFile = path.join(__dirname, '..', 'tools', 'Get-VS7.cs');
17+
const cmd = 'powershell -ExecutionPolicy Unrestricted -Command ' +
18+
'"&{ Add-Type -Path ' + csFile + '; [VisualStudioConfiguration.Program]::Main(@())}"'
19+
const vsSetupRaw = cp.execSync(cmd).toString();
1820
if (!vsSetupRaw) return;
1921
const vsSetup = vsSetupRaw.split(/[\r|\n]/g).reduce((s, l) => {
2022
const lParts = l.split(': ');
@@ -27,12 +29,32 @@ function tryVS7 (gyp) {
2729
}
2830
}
2931

32+
function tryVS7_registry(gyp) {
33+
const magicKey = String.raw`HKLM\Software\Microsoft\VisualStudio\SxS\VS7`;
34+
const magicQuery = `reg query ${magicKey} /reg:32`;
35+
const qRet = cp.execSync(magicQuery).toString().trim();
36+
if (qRet.includes('ERROR')) {
37+
gyp.bindings.log('Couldn\'t find VS7 in registry:(');
38+
return;
39+
}
40+
const values = qRet.split(/[\r|\n]+/g).slice(1);
41+
const ret = values.map(v => {
42+
const parts = v.trim().replace(/\s+/g, ' ').split(' ');
43+
return [Number(parts[0]), parts[2]];
44+
});
45+
if (!ret.length) {
46+
gyp.bindings.log('Couldn\'t find VS7 in registry');
47+
return;
48+
}
49+
const maxVer = Math.max.apply(Math, ret.map(v => v[0]));
50+
return ret.find(v => v[0] === maxVer)[1];
51+
}
3052

3153
function locateMsbuild(gyp, callback) {
32-
var vsSetup = tryVS7(gyp)
54+
const vsSetup = tryVS7_COM(gyp) || tryVS7_registry(gyp);
3355
if (!vsSetup)return callback()
3456

35-
var msbuild_location = path.join(vsSetup.InstallationPath, 'MSBuild',
57+
const msbuild_location = path.join(vsSetup.InstallationPath, 'MSBuild',
3658
'15.0', 'Bin', 'MSBuild.exe')
3759
log.verbose('find vs2017', 'looking for msbuild in %s', msbuild_location)
3860
fs.access(msbuild_location, function(err) {
@@ -42,7 +64,7 @@ function locateMsbuild(gyp, callback) {
4264

4365

4466
function setGypVS2017Env(gyp, callback) {
45-
var vsSetup = tryVS7(gyp);
67+
const vsSetup = tryVS7_COM(gyp) || tryVS7_registry(gyp);
4668
if (!vsSetup)return callback()
4769

4870
gyp.opts.msvs_version = '2017';

tools/Get-VS7.cs

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
// powershell -ExecutionPolicy Unrestricted -Version "2.0" -Command "&{ Add-Type -Path Program.cs; [VisualStudioConfiguration.Program]::Main(@())}"
2+
using System;
3+
using System.Runtime.InteropServices;
4+
5+
namespace VisualStudioConfiguration
6+
{
7+
[Flags]
8+
public enum InstanceState : uint
9+
{
10+
None = 0,
11+
Local = 1,
12+
Registered = 2,
13+
NoRebootRequired = 4,
14+
NoErrors = 8,
15+
Complete = 4294967295,
16+
}
17+
18+
[Guid("6380BCFF-41D3-4B2E-8B2E-BF8A6810C848")]
19+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
20+
[ComImport]
21+
public interface IEnumSetupInstances
22+
{
23+
24+
void Next([MarshalAs(UnmanagedType.U4), In] int celt,
25+
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface), Out] ISetupInstance[] rgelt,
26+
[MarshalAs(UnmanagedType.U4)] out int pceltFetched);
27+
28+
void Skip([MarshalAs(UnmanagedType.U4), In] int celt);
29+
30+
void Reset();
31+
32+
[return: MarshalAs(UnmanagedType.Interface)]
33+
IEnumSetupInstances Clone();
34+
}
35+
36+
[Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")]
37+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
38+
[ComImport]
39+
public interface ISetupConfiguration
40+
{
41+
}
42+
43+
[Guid("26AAB78C-4A60-49D6-AF3B-3C35BC93365D")]
44+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
45+
[ComImport]
46+
public interface ISetupConfiguration2 : ISetupConfiguration
47+
{
48+
49+
[return: MarshalAs(UnmanagedType.Interface)]
50+
IEnumSetupInstances EnumInstances();
51+
52+
[return: MarshalAs(UnmanagedType.Interface)]
53+
ISetupInstance GetInstanceForCurrentProcess();
54+
55+
[return: MarshalAs(UnmanagedType.Interface)]
56+
ISetupInstance GetInstanceForPath([MarshalAs(UnmanagedType.LPWStr), In] string path);
57+
58+
[return: MarshalAs(UnmanagedType.Interface)]
59+
IEnumSetupInstances EnumAllInstances();
60+
}
61+
62+
[Guid("B41463C3-8866-43B5-BC33-2B0676F7F42E")]
63+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
64+
[ComImport]
65+
public interface ISetupInstance
66+
{
67+
}
68+
69+
[Guid("89143C9A-05AF-49B0-B717-72E218A2185C")]
70+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
71+
[ComImport]
72+
public interface ISetupInstance2 : ISetupInstance
73+
{
74+
[return: MarshalAs(UnmanagedType.BStr)]
75+
string GetInstanceId();
76+
77+
[return: MarshalAs(UnmanagedType.Struct)]
78+
System.Runtime.InteropServices.ComTypes.FILETIME GetInstallDate();
79+
80+
[return: MarshalAs(UnmanagedType.BStr)]
81+
string GetInstallationName();
82+
83+
[return: MarshalAs(UnmanagedType.BStr)]
84+
string GetInstallationPath();
85+
86+
[return: MarshalAs(UnmanagedType.BStr)]
87+
string GetInstallationVersion();
88+
89+
[return: MarshalAs(UnmanagedType.BStr)]
90+
string GetDisplayName([MarshalAs(UnmanagedType.U4), In] int lcid);
91+
92+
[return: MarshalAs(UnmanagedType.BStr)]
93+
string GetDescription([MarshalAs(UnmanagedType.U4), In] int lcid);
94+
95+
[return: MarshalAs(UnmanagedType.BStr)]
96+
string ResolvePath([MarshalAs(UnmanagedType.LPWStr), In] string pwszRelativePath);
97+
98+
[return: MarshalAs(UnmanagedType.U4)]
99+
InstanceState GetState();
100+
101+
[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)]
102+
ISetupPackageReference[] GetPackages();
103+
104+
ISetupPackageReference GetProduct();
105+
106+
[return: MarshalAs(UnmanagedType.BStr)]
107+
string GetProductPath();
108+
109+
[return: MarshalAs(UnmanagedType.VariantBool)]
110+
bool IsLaunchable();
111+
112+
[return: MarshalAs(UnmanagedType.VariantBool)]
113+
bool IsComplete();
114+
115+
ISetupPropertyStore GetProperties();
116+
117+
[return: MarshalAs(UnmanagedType.BStr)]
118+
string GetEnginePath();
119+
}
120+
121+
[Guid("DA8D8A16-B2B6-4487-A2F1-594CCCCD6BF5")]
122+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
123+
[ComImport]
124+
public interface ISetupPackageReference
125+
{
126+
127+
[return: MarshalAs(UnmanagedType.BStr)]
128+
string GetId();
129+
130+
[return: MarshalAs(UnmanagedType.BStr)]
131+
string GetVersion();
132+
133+
[return: MarshalAs(UnmanagedType.BStr)]
134+
string GetChip();
135+
136+
[return: MarshalAs(UnmanagedType.BStr)]
137+
string GetLanguage();
138+
139+
[return: MarshalAs(UnmanagedType.BStr)]
140+
string GetBranch();
141+
142+
[return: MarshalAs(UnmanagedType.BStr)]
143+
string GetType();
144+
145+
[return: MarshalAs(UnmanagedType.BStr)]
146+
string GetUniqueId();
147+
148+
[return: MarshalAs(UnmanagedType.VariantBool)]
149+
bool GetIsExtension();
150+
}
151+
152+
[Guid("c601c175-a3be-44bc-91f6-4568d230fc83")]
153+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
154+
[ComImport]
155+
public interface ISetupPropertyStore
156+
{
157+
158+
[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]
159+
string[] GetNames();
160+
161+
object GetValue([MarshalAs(UnmanagedType.LPWStr), In] string pwszName);
162+
}
163+
164+
[Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")]
165+
[CoClass(typeof(SetupConfigurationClass))]
166+
[TypeLibImportClass(typeof(SetupConfigurationClass))]
167+
[ComImport]
168+
public interface SetupConfiguration : ISetupConfiguration2, ISetupConfiguration
169+
{
170+
}
171+
172+
[Guid("177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D")]
173+
[ClassInterface(ClassInterfaceType.None)]
174+
[ComImport]
175+
public class SetupConfigurationClass
176+
{
177+
}
178+
179+
public static class Program
180+
{
181+
public static int Main(string[] args)
182+
{
183+
try
184+
{
185+
ISetupConfiguration query = new SetupConfiguration();
186+
ISetupConfiguration2 query2 = (ISetupConfiguration2) query;
187+
IEnumSetupInstances e = query2.EnumAllInstances();
188+
ISetupInstance2[] rgelt = new ISetupInstance2[1];
189+
int pceltFetched;
190+
do
191+
{
192+
e.Next(1, rgelt, out pceltFetched);
193+
if (pceltFetched > 0)
194+
PrintInstance(rgelt[0]);
195+
} while (pceltFetched > 0);
196+
return 0;
197+
}
198+
catch (Exception ex)
199+
{
200+
Console.Error.WriteLine("Error 0x{0:x8}: {1}", ex, ex.Message);
201+
return 1;
202+
}
203+
}
204+
205+
private static void PrintInstance(ISetupInstance2 setupInstance2)
206+
{
207+
Console.WriteLine("InstallationPath: {0}", setupInstance2.GetInstallationPath());
208+
Console.WriteLine("Product: {0}", setupInstance2.GetProduct().GetId());
209+
foreach (ISetupPackageReference package in setupInstance2.GetPackages())
210+
{
211+
if (package.GetType() != "Exe") continue;
212+
string id = package.GetId();
213+
if (id.IndexOf("SDK", StringComparison.Ordinal) == -1) continue;
214+
string[] parts = id.Split('_');
215+
if (parts.Length < 2) continue;
216+
string sdkVer = parts[1];
217+
char[] chars = {'1', '0', '8'};
218+
if (sdkVer.IndexOfAny(chars) == -1) continue;
219+
Console.WriteLine("SDK: {0}", sdkVer);
220+
}
221+
Console.WriteLine();
222+
}
223+
}
224+
}

0 commit comments

Comments
 (0)