Skip to content

Instantly share code, notes, and snippets.

@noseratio
Last active May 2, 2023 11:31
Show Gist options
  • Save noseratio/d81888eda77620e526c7eb2c3b75cba8 to your computer and use it in GitHub Desktop.
Save noseratio/d81888eda77620e526c7eb2c3b75cba8 to your computer and use it in GitHub Desktop.
A workaround for "node-gyp is unable to find msbuild if VS2019 is installed": https://github.com/nodejs/node-gyp/issues/1663
<#
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"
@noseratio
Copy link
Author

noseratio commented Jun 26, 2019

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?

@k1epto
Copy link

k1epto commented Jun 26, 2019

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

@noseratio
Copy link
Author

noseratio commented Jun 26, 2019

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment