From 3bdda34e239fba5805414fcff76c1ef7b59b20ff Mon Sep 17 00:00:00 2001 From: Lucas Cloarec Date: Fri, 2 Jul 2021 10:57:39 +0200 Subject: [PATCH 1/3] Fix: findVisualStudio with pwsh constrained lang. mode 'Add-Type' cannot be used in powershell with constrained language mode. Language mode does not exist in PowerShell 2.0 engine. To force powershell to use 2.0 engine allows the usage of msvc 2017 or newer in environment with constrained language mode. See : https://devblogs.microsoft.com/powershell/powershell-constrained-language-mode/ https://docs.microsoft.com/en-us/powershell/scripting/windows-powershell/starting-the-windows-powershell-2.0-engine?view=powershell-7.1 --- lib/find-visualstudio.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/find-visualstudio.js b/lib/find-visualstudio.js index f2cce327e7..45b5ba4847 100644 --- a/lib/find-visualstudio.js +++ b/lib/find-visualstudio.js @@ -129,6 +129,8 @@ VisualStudioFinder.prototype = { 'WindowsPowerShell', 'v1.0', 'powershell.exe') var csFile = path.join(__dirname, 'Find-VisualStudio.cs') var psArgs = [ + '-Version', + '2', '-ExecutionPolicy', 'Unrestricted', '-NoProfile', From 0595377b556b6b806ed84cbe0be8f6a2f59cff57 Mon Sep 17 00:00:00 2001 From: Lucas Cloarec Date: Wed, 14 Sep 2022 12:32:16 +0200 Subject: [PATCH 2/3] refactor findVisualStudio2017OrNewer to try to use powershell V2 only if language mode is not FullLanguage --- lib/find-visualstudio.js | 55 +++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/lib/find-visualstudio.js b/lib/find-visualstudio.js index 6c315dab14..be0ca6a814 100644 --- a/lib/find-visualstudio.js +++ b/lib/find-visualstudio.js @@ -120,31 +120,46 @@ VisualStudioFinder.prototype = { this.log.error(`\n${errorLog}\n\n${infoLog}\n`) process.nextTick(this.callback.bind(null, new Error( - 'Could not find any Visual Studio installation to use'))) + 'Could not find any Visual Studio installation to use'))) }, // Invoke the PowerShell script to get information about Visual Studio 2017 // or newer installations - findVisualStudio2017OrNewer: function findVisualStudio2017OrNewer (cb) { - var ps = path.join(process.env.SystemRoot, 'System32', - 'WindowsPowerShell', 'v1.0', 'powershell.exe') - var csFile = path.join(__dirname, 'Find-VisualStudio.cs') - var psArgs = [ - '-Version', - '2', - '-ExecutionPolicy', - 'Unrestricted', - '-NoProfile', - '-Command', - '&{Add-Type -Path \'' + csFile + '\';' + '[VisualStudioConfiguration.Main]::PrintJson()}' - ] - + findVisualStudio2017OrNewer: function findVisualStudio2017OrNewer(cb) { + const ps = path.join(process.env.SystemRoot, 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe') + const csFile = path.join(__dirname, 'Find-VisualStudio.cs') + const basePsArgs = ['-ExecutionPolicy', 'Unrestricted', '-NoProfile', '-Command',] + const findLanguageModePsCmd = + `&{ try { $ExecutionContext.SessionState.LanguageMode } catch { try { (Get-PSSessionConfiguration -Name Test).LanguageMode } catch { 'error' } } }` + + const psArgs = [...basePsArgs, findLanguageModePsCmd] this.log.silly('Running', ps, psArgs) - var child = execFile(ps, psArgs, { encoding: 'utf8' }, - (err, stdout, stderr) => { - this.parseData(err, stdout, stderr, cb) - }) - child.stdin.end() + const childFindPsLanguageMode = execFile( + ps, + psArgs, + {encoding: 'utf8'}, + (err, stdout, stderr) => { + this.log.silly('PS stderr = %j', stderr) + if (err) { + this.log.silly('PS err = %j', err && (err.stack || err)) + this.addLog( + 'could not determine PowerShell LanguageMode, try re-running with \'--loglevel silly\' for more details') + return cb(null) + } + const findVscDataPsCmd = `&{Add-Type -Path '${csFile}';[VisualStudioConfiguration.Main]::PrintJson()}` + const psArgs = [...basePsArgs, findVscDataPsCmd] + // the Add-Type command requires powershell to run with languageMode == FullLanguage + // Because languageMode feature is not introduced yet in powershell v2, we can try to use it. + // If powershell v2 is not installed (a problem only if languageMode is not FullLanguage), then it is not + // possible to use feature Add-Type. + if (stdout.toString('utf8').trim().toLowerCase() !== 'fulllanguage') { + psArgs.unshift('-Version', '2',) + } + this.log.silly('Running', ps, psArgs) + const child = execFile(ps, psArgs, {encoding: 'utf8'}, (err, stdout, stderr) => this.parseData(err, stdout, stderr, cb)) + child.stdin.end() + }) + childFindPsLanguageMode.stdin.end() }, // Parse the output of the PowerShell script and look for an installation From 9d330d13847e810ed8a62a9b016b87532ff87768 Mon Sep 17 00:00:00 2001 From: Lucas Cloarec Date: Wed, 14 Sep 2022 16:15:07 +0200 Subject: [PATCH 3/3] try to fix style issue --- lib/find-visualstudio.js | 56 ++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/lib/find-visualstudio.js b/lib/find-visualstudio.js index be0ca6a814..a99572328d 100644 --- a/lib/find-visualstudio.js +++ b/lib/find-visualstudio.js @@ -120,45 +120,45 @@ VisualStudioFinder.prototype = { this.log.error(`\n${errorLog}\n\n${infoLog}\n`) process.nextTick(this.callback.bind(null, new Error( - 'Could not find any Visual Studio installation to use'))) + 'Could not find any Visual Studio installation to use'))) }, // Invoke the PowerShell script to get information about Visual Studio 2017 // or newer installations - findVisualStudio2017OrNewer: function findVisualStudio2017OrNewer(cb) { + findVisualStudio2017OrNewer: function findVisualStudio2017OrNewer (cb) { const ps = path.join(process.env.SystemRoot, 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe') const csFile = path.join(__dirname, 'Find-VisualStudio.cs') - const basePsArgs = ['-ExecutionPolicy', 'Unrestricted', '-NoProfile', '-Command',] + const basePsArgs = ['-ExecutionPolicy', 'Unrestricted', '-NoProfile', '-Command'] const findLanguageModePsCmd = - `&{ try { $ExecutionContext.SessionState.LanguageMode } catch { try { (Get-PSSessionConfiguration -Name Test).LanguageMode } catch { 'error' } } }` + '&{ try { $ExecutionContext.SessionState.LanguageMode } catch { try { (Get-PSSessionConfiguration -Name Test).LanguageMode } catch { \'error\' } } }' const psArgs = [...basePsArgs, findLanguageModePsCmd] this.log.silly('Running', ps, psArgs) const childFindPsLanguageMode = execFile( - ps, - psArgs, - {encoding: 'utf8'}, - (err, stdout, stderr) => { - this.log.silly('PS stderr = %j', stderr) - if (err) { - this.log.silly('PS err = %j', err && (err.stack || err)) - this.addLog( - 'could not determine PowerShell LanguageMode, try re-running with \'--loglevel silly\' for more details') - return cb(null) - } - const findVscDataPsCmd = `&{Add-Type -Path '${csFile}';[VisualStudioConfiguration.Main]::PrintJson()}` - const psArgs = [...basePsArgs, findVscDataPsCmd] - // the Add-Type command requires powershell to run with languageMode == FullLanguage - // Because languageMode feature is not introduced yet in powershell v2, we can try to use it. - // If powershell v2 is not installed (a problem only if languageMode is not FullLanguage), then it is not - // possible to use feature Add-Type. - if (stdout.toString('utf8').trim().toLowerCase() !== 'fulllanguage') { - psArgs.unshift('-Version', '2',) - } - this.log.silly('Running', ps, psArgs) - const child = execFile(ps, psArgs, {encoding: 'utf8'}, (err, stdout, stderr) => this.parseData(err, stdout, stderr, cb)) - child.stdin.end() - }) + ps, + psArgs, + { encoding: 'utf8' }, + (err, stdout, stderr) => { + this.log.silly('PS stderr = %j', stderr) + if (err) { + this.log.silly('PS err = %j', err && (err.stack || err)) + this.addLog( + 'could not determine PowerShell LanguageMode, try re-running with \'--loglevel silly\' for more details') + return cb(null) + } + const findVscDataPsCmd = `&{Add-Type -Path '${csFile}';[VisualStudioConfiguration.Main]::PrintJson()}` + const psArgs = [...basePsArgs, findVscDataPsCmd] + // the Add-Type command requires powershell to run with languageMode == FullLanguage + // Because languageMode feature is not introduced yet in powershell v2, we can try to use it. + // If powershell v2 is not installed (a problem only if languageMode is not FullLanguage), then it is not + // possible to use feature Add-Type. + if (stdout.toString('utf8').trim().toLowerCase() !== 'fulllanguage') { + psArgs.unshift('-Version', '2') + } + this.log.silly('Running', ps, psArgs) + const child = execFile(ps, psArgs, { encoding: 'utf8' }, (err, stdout, stderr) => this.parseData(err, stdout, stderr, cb)) + child.stdin.end() + }) childFindPsLanguageMode.stdin.end() },