Rui Liu of WRI tech support has this to say about Run:
Hello,
Thank you for the email.
My apologies for the delay in getting back to you regarding this.
The following is a fairly technical description, but it shows what's
really
going on,
First let's see how the function Run[] works currently.
All of the argument strings are StringJoined together into a single
string, with spaces between each argument. (This means there's
really nothing special to using the multi-argument form. From now
on, here the single-argument form of Run is used for simplicity.)
Run["dir",".exe"] --> Run["dir *.exe"]
Then that string is passed to the C function system().
Now, on Windows, system() takes the string its given and precedes it
with the string "cmd /c ". This runs the standard Windows shell
cmd.exe, sometimes called the "DOS prompt," with the /c argument
meaning "run the following command, and return when finished."
So, for instance, Run["dir *.exe"] eventually becomes (inside
the C run-time library), a call to start "cmd.exe" with a command
line of:
cmd.exe /c dir *.exe
Here is how you can use this information to decide how to quote
things for Run: try your example out on in the command prompt.
You can get a command prompt in Windows by going to the Start menu,
choosing Run, and entering "cmd" into the Run box. This will give
you a command prompt window.
For instance:
(1) Should you add special quotes to either dir or *.exe?
Try at the command prompt:
cmd.exe /c dir *.exe
and you see this works fine without adding quotes. So in
Mathematica:
Run["dir *.exe"]
works fine, too.
(2) What about getting a directory of C:\Program Files\Windows NT\*.exe
?
Try at the command prompt:
cmd.exe /c dir C:\Program Files\Windows NT\*.exe
This doesn't work. So let's try some quote marks:
cmd.exe /c dir "C:\Program Files\Windows NT\*.exe"
This does work (it will show dialer.exe and HYPERTRM.EXE).
So this means it needs to add explicit quote marks when the function
Run[] is called:
In[1]:= Run["dir \"C:\\Program Files\\Windows NT\\*.exe\""]
(Notice that I had to "escape" both the double-quotes and the
path-separating backslashes.)
A lot of the weird behavior of Run is coming from the weird behavior
of cmd.exe, really. So playing around with cmd can help you figure out
what you need to pass to Run to make it work.
Also, while fiddling with the Run[] function it can be best to use
math.exe
rather than Mathematica.exe. The reason is that
math.exe outputs to the console (the command prompt window that
cmd.exe uses), so you can see any error messages that cmd.exe prints
along with Mathematica's output.
Here let's look at your examples:
(1) How to run something in a directory with spaces. Try this in
cmd.exe first:
C:\> cmd /c C:\Documents and Settings\user\finalproject.bat hi up
'C:\Documents' is not recognized as an internal or external command,
operable program or batch file.
It's treating the first space as the end of the program name to run,
and all the words that follow (starting with "and") as arguments to
this nonexistent program "C:\Documents". So let's quote the program
name:
C:\> cmd /c "C:\Documents and Settings\user\finalproject.bat" hi up
hello hi what is up
That works, so it means that Run needs quotes around the program
name:
In[1]:= Run["\"C:\\Documents and Settings\\user\\finalproject.bat\"
hi
up"]
(2) What about quoting both the program name and the arguments?
Here we seem to run into a bug in cmd.exe.
C:\> cmd /c "C:\Documents and Settings\user\finalproject.bat" "hi
up"
'C:\Documents' is not recognized as an internal or external command,
operable program or batch file.
That seems wrong. It ought to run the program with one argument,
the
string "hi up", displaying: hello "hi up" what is
But instead it gets totally confused.
So let's play around with more quotes, by putting quotes around each
element, AND around the whole thing.
C:\> cmd /c ""C:\Documents and Settings\user\finalproject.bat" "hi
up""
hello "hi up" what is
Success! I don't know why. But this tell you what you have to do
if
you want to Run a program with spaces in its name that takes
arguments
with spaces in them: quote both the executable path, the arguments,
and the whole thing.
In[2]:= Run["\"\"C:\\Documents and
Settings\\user\\finalproject.bat\"
\"hi up\"\""]
hello "hi up" what is
(3) This double-double-quoting approach also works when the executable
path
name doesn't have any spaces in it.
C:\> cd "Documents and Settings"
C:\Documents and Settings> cmd /c ""user\finalproject.bat" "hi up""
hello "hi up" what is
And in Mathematica ...
SetDirectory["C:\\Documents and Settings"]
Run["\"\"user\\finalproject.bat\" \"hi up\"\""]
hello "hi up" what is
Of course, in the last case you don't really need all the quotes.
Just Run["user\\finalproject.bat \"hi up\""] will do. But I believe
you're trying to come up with some system that is sure to work no
matter
whether the path has spaces, or whether the arguments are quoted.
It looks like the double-double-quote approach does the job.
And remember, if you're having trouble, at all times you can always
ask cmd.exe /c what it wants. That's all Run[] is doing.
Sincerely,
Rui Liu
Technical Support
Wolfram Research, Inc.
support at wolfram.com