Last active
January 22, 2023 11:05
-
-
Save roryrjb/61474fc748e43515c060895e91248791 to your computer and use it in GitHub Desktop.
npm.exe: a bad hack for when your Node.js project that spawns npm isn't quite portable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define WIN32_LEAN_AND_MEAN | |
#include <windows.h> | |
#pragma comment(lib, "Shlwapi.lib") | |
/* Find the end of argv[0]. */ | |
static WCHAR * | |
findargs(WCHAR *s) | |
{ | |
if (s[0] == 34) | |
{ | |
/* quoted argv[0] */ | |
for (s++;; s++) | |
{ | |
switch (*s) | |
{ | |
case 0: | |
return s; | |
case 34: | |
return s + 1; | |
} | |
} | |
} | |
else | |
{ | |
/* unquoted argv[0] */ | |
for (;; s++) | |
{ | |
switch (*s) | |
{ | |
case 0: | |
case 9: | |
case 32: | |
return s; | |
} | |
} | |
} | |
} | |
int wmain(int argc, wchar_t *argv[]) | |
{ | |
WCHAR npm_path[MAX_PATH] = L"\\node_modules\\npm\\bin\\npm-cli.js"; | |
WCHAR root_path[MAX_PATH]; | |
WCHAR node_path[MAX_PATH]; | |
WCHAR lib_path[MAX_PATH * 2]; | |
WCHAR cmd[MAX_PATH * 2] = L""; | |
GetModuleFileNameW(NULL, root_path, MAX_PATH); | |
if (!PathRemoveFileSpecW(root_path, MAX_PATH)) | |
return 1; | |
wcscpy(node_path, root_path); | |
wcscpy(lib_path, root_path); | |
wcscat(node_path, L"\\node.exe"); | |
wcscat(lib_path, npm_path); | |
WCHAR *args = findargs(GetCommandLineW()); | |
wcscat(cmd, L"-- \""); | |
wcscat(cmd, lib_path); | |
wcscat(cmd, L"\""); | |
wcscat(cmd, args); | |
STARTUPINFOW si; | |
GetStartupInfoW(&si); | |
PROCESS_INFORMATION process; | |
if (!CreateProcessW(node_path, cmd, 0, 0, TRUE, 0, 0, 0, &si, &process)) | |
{ | |
return 1; | |
} | |
DWORD ret; | |
WaitForSingleObject(process.hProcess, INFINITE); | |
GetExitCodeProcess(process.hProcess, &ret); | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A baddddd hack. It allows you to spawn
npm
(notnpm.cmd
) without running a shell directly. This is not a solution for 99.99% of cases.You can compile your own
npm.exe
with a VS build tools shell and simply usecl
(I'm sure it works with MinGW as well). Place thenpm.exe
next to wherenode.exe
is in your Node.js installation. You can tweak the above fornpx
if needed.Some the code above was taken from the w64devkit project.