gulp-run icon indicating copy to clipboard operation
gulp-run copied to clipboard

Cannot call program with spaces in path on Windows

Open borekb opened this issue 10 years ago • 7 comments

I have a code like this:

$command = '"C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\Common7\\IDE\\devenv.exe" "..\\MySolution.sln" /run';
run($command).exec();

However, it fails with

'"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\devenv.exe"' is not recognized as an internal or external command, operable program or batch file.

I think the string is quoted correctly in my code, isn't it?

borekb avatar Feb 24 '15 13:02 borekb

Unfortunately, I don't have a Windows machine to work on this. Does this happen with the usePowerShell option?

cbarrick avatar Feb 24 '15 15:02 cbarrick

The escaping is wrong in both cases. The problem is on this line: https://github.com/cbarrick/gulp-run/blob/master/lib/command.js#L79 where the command is properly quoted but but childProcess.spawn() maybe transforms it somehow, I don't know, but when I take the output of this line: https://github.com/cbarrick/gulp-run/blob/master/lib/command.js#L99 and just copy it to cmd.exe like this:

cmd /c <copy/pasted command here>

it works. So it must be something inside the childProcess.spawn() I think.

BTW Windows 10 is available for free so if you need a testing VM it should be relatively simple to create one, compared to the past.

borekb avatar Feb 25 '15 10:02 borekb

On Unix, sh -c COMMAND expects all of the command to be a single argument to sh (i.e. enclosed in quotes when typing into a terminal), but on Windows it seems that cmd /c COMMAND expects each argument of the command to be a separate argument to cmd.exe. So the command string needs to be split into discrete arguments on Windows before handing it off to childProcess.spawn().

That's my hunch anyway. I'll look into setting up a Windows VM to test it out.

Source: http://ss64.com/nt/cmd.html

cbarrick avatar Feb 25 '15 20:02 cbarrick

According to that same site,powershell -Command COMMAND expects the command as a single argument, so you may be able to setup powershell as a workaround until this gets fixed.

cbarrick avatar Feb 25 '15 20:02 cbarrick

I pushed an untested fix as c5ad8a0. When I test it, and if it works, I'll push it to npm.

cbarrick avatar Feb 26 '15 15:02 cbarrick

Another interesting test case that just came to mind - the command can be something like:

cmd1.exe && cmd2.exe

This executes fine on cmd.exe, like:

cmd /c cmd1.exe && cmd2.exe

and so it should on gulp-run as well. Thanks for your effort!

borekb avatar Feb 26 '15 15:02 borekb

That use case is definitely important to this project. Actually, that's why I chose to run commands through a subshell rather than executing them directly. All higher-level shell features are supposed to work, so if they don't, it's a bug.

That being said, I'm a total Windows noob and have no idea how higher-level shell features are handled in cmd.exe. Upon further reading, I may have been wrong about my previous conclusions.

If /C or /K is specified, then the remainder of the command line is processed as an immediate command in the new shell. Multiple commands separated by the command separator '&' or '&&' are accepted if surrounded by quotes.

So it seems that commands SHOULD work as both a single argument and multiple arguments, but they MUST be single arguments to support higher-level shell features like &&. However, I don't know how cmd.exe passes arguments, so I don't know if the quotes get passed along. I'll have to do some more testing to see how the quotes should be handled.

cbarrick avatar Feb 26 '15 16:02 cbarrick