-
-
Save noseratio/d81888eda77620e526c7eb2c3b75cba8 to your computer and use it in GitHub Desktop.
<# | |
This is a workaround for "node-gyp is unable to find msbuild if VS2019 is installed" | |
https://github.com/nodejs/node-gyp/issues/1663 | |
It create a shim EXE as "MSBuild\15.0\Bin\MSBuild.exe" to target "MSBuild\Current\Bin\MSBuild.exe" | |
By noseratio - MIT license - use at your own risk! | |
It requires admin mode, I use wsudo/wsudox (https://chocolatey.org/packages/wsudo) for that: | |
wsudo powershell -f make-msbuild-shim.ps1 | |
#> | |
#Requires -RunAsAdministrator | |
#Requires -Version 5.1 | |
$ErrorActionPreference = "Stop" | |
$vsBasePath = . "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" ` | |
-latest ` | |
-requires Microsoft.Component.MSBuild ` | |
-property installationPath -format value | |
if (!$vsBasePath) { | |
throw "VS2017+ must be installed" | |
} | |
$msbuildSimPath = [System.IO.Path]::Combine($vsBasePath, "MSBuild\15.0\Bin\MSBuild.exe") | |
if ([System.IO.File]::Exists($msbuildSimPath)) { | |
Write-Host "Already exists: $msbuildSimPath" | |
exit 0; | |
} | |
# Create the shim .EXE using C# | |
$code = @" | |
using System; | |
using System.Diagnostics; | |
using System.IO; | |
using System.Linq; | |
static class MSBuildShim | |
{ | |
static void Main() | |
{ | |
var thisExe = Process.GetCurrentProcess().MainModule.FileName; | |
var thisExeDir = Path.GetDirectoryName(thisExe); | |
var newExe = Path.GetFullPath(Path.Combine(thisExeDir, "..\\..\\Current\\Bin", "MSBuild.exe")); | |
if (!File.Exists(newExe)) | |
throw new FileNotFoundException(newExe); | |
var process = new Process(); | |
process.StartInfo.FileName = newExe; | |
process.StartInfo.Arguments = String.Join("\u0020", Environment.GetCommandLineArgs().Skip(1)); | |
process.StartInfo.UseShellExecute = false; | |
if (!process.Start()) | |
throw new InvalidOperationException(newExe); | |
process.WaitForExit(); | |
Environment.ExitCode = process.ExitCode; | |
} | |
} | |
"@ | |
Add-Type -TypeDefinition $code ` | |
-OutputType ConsoleApplication ` | |
-OutputAssembly "$msbuildSimPath" ` | |
-ReferencedAssemblies "System.Core.dll" | |
Write-Host "Shim created at: $msbuildSimPath" |
doesn't run for me, errors
@bipolarmorgan: That's not enough of diagnostics info for fixing anything, but make sure you use PowerShell (not PowerShell Core!) and run the script as admin.
I've tried this script. Ran it, and then ran it again to make sure it ran properly :
PS C:\> .\make-msbuild-shim.ps1 Already exists: C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\15.0\Bin\MSBuild.exe
Running npm install (which triggers a node-gyp build of node-sass), I still get node-gyp trying to spawn build tools at the wrong location - 15.0\Bin\MSBuild.exe rather than MSBuild\Current\Bin:
gyp ERR! UNCAUGHT EXCEPTION gyp ERR! stack Error: spawn C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\15.0\Bin\MSBuild.exe ENOENT gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:264:19) gyp ERR! stack at onErrorNT (internal/child_process.js:456:16) gyp ERR! stack at processTicksAndRejections (internal/process/task_queues.js:84:9) gyp ERR! System Windows_NT 10.0.17763
@spiraljacobs, it still runs as C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\15.0\Bin\MSBuild.exe
, as far as node-gyp is concerned. This file is just a shim generated by my powershell script, and it invokes MSBuild\Current\Bin\MSBuild.exe
as a child process.
It's hard to tell why it is not working on your system as expected, but you should not be using it anyway, rather use node-gyp 5.0 that comes with VS2019 support.
Ah, when I was installing node-gyp@latest, didn't seem to be pulling anything that supported 2019.
Anyway, thanks for the help!
doesn't run for me, errors
@bipolarmorgan: That's not enough of diagnostics info for fixing anything, but make sure you use PowerShell (not PowerShell Core!) and run the script as admin.
True it's not, but you also didn't ask for any information, you assumed your script works... when it doesn't.
Cannot process the "#requires" statement at line 10 because it is not in the correct format.
The "#requires" statement must be in one of the following formats:
"#requires -shellid <shellID>"
"#requires -version <major.minor>"
"#requires -pssnapin <psSnapInName> [-version <major.minor>]"
At line:1 char:30
+ c:\temp\make-msbuild-shim.ps1 <<<<
+ CategoryInfo : ObjectNotFound: (:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Cannot process the "#requires" statement at line 10 because it is not in the correct format.
@bipolarmorgan, on the machine where you're getting this error, can you go to the admin command prompt and run powershell get-host
What is the output?
C:\Users\User>powershell
Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.
PS C:\Users\User> get-host
Name : ConsoleHost
Version : 2.0
InstanceId : 92b8f577-b391-4aa6-aae5-8cb6beb4cf45
UI : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture : en-US
CurrentUICulture : en-US
PrivateData : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
IsRunspacePushed : False
Runspace : System.Management.Automation.Runspaces.LocalRunspace
Name : ConsoleHost
Version : 2.0
@bipolarmorgan, so this is Windows 7 with PowerShell 2.0 and that's why you're seeing this error. You need PowerShell 5.1, as you could tell from #Requires -Version 5.1
. You can get it here: https://chocolatey.org/packages/powershell.
Better yet, use the new node-gyp 5.0 and never mind this gist, it was meant to be a workaround until node-gyp properly supports VS2019.
That said, I'm not sure VS2019 is even supported on Windows 7, as the latter reaches its End of Life phase on January 14, 2020.
doesn't run for me, errors