execute_process 'Access is denied' for npm update.


I’m using cmake 3.28.3 on Windows 10 and trying to use execute_process to call ‘npm update’ after copying package.json to binary dir.

With plain “COMMAND npm update” cmake couldn’t find npm, so I tried using the find_program path for NPM.

This returns a valid path (“C:/Program Files/nodejs/npm”) but it contains a space which aways gets me hella confused. I tried this:


…and got…

%1 is not a valid Win32 application

I tried this:

COMMAND “${NPM_PATH}” update

…and got the same thing. I tried this:

COMMAND \“${NPM_PATH}\” update

…and got…

Access is denied.

I’m guessing I’ve correctly escaped spaces here (and I can sort of see what’s going on having used system() in C myself) but there seems to be a permissions problem of some kind, maybe because the command I want is in Program Files?

I can install the modules globally in the meantime to work around this, but it’d be nice to get the ‘local’ version working.

Does anyone know what’s up and how to fix this?


OK, I’ve discovered several things, first C:/Program Files/nodejs is actually a shortcut to a dir in C:/Users/etc/AppData/blah…

Futhermore, the file ‘npm’ is bash script. The windows version is called npm.cmd (not npm.bat?)

Kind of suprised I can use ‘npm’ from gitbash/command prompt at all.

The good news is if I use full path to real npm.cmd file, npm update works in cmake.

The bad news this solution will only work for me…


COMMAND cmd /C npm update

But what’s strange is that I don’t have the same problem with “COMMAND npx node-gyp build”…that just works even though npx is in the same dir as npm, is also not a bat file etc etc, they seem to be identical. Might do the cmd /C thing for both…

The documentation of execute_process explains, that is uses the Windows API directly to execute processes. There is no shell involved.

So any shell script (regardless if .bat or .cmd), won’t work. You have to call the interpreter explicitly.

Only executables .exe or .com are supported by Windows API.

OK, that explains it, thanks.

On the other hand, add_custom_command does seem to ‘use a shell’ (that’s why npx is working) which I think is what have may initially have confused me.