Calling .exe with Arguments - Run[] Issue

244 views
Skip to first unread message

Shyam Guthikonda

unread,
Apr 27, 2006, 2:50:41 AM4/27/06
to
Ugh.. I've spent the past couple hours trying to figure this out. No
luck in the archives either.

This works (Windows XP, Mathematica 5.2), passing the string OK as the
first argument to the C program:

Run[ InputForm[ folderName<>"\\"<>exeName ], "OK" ];

This does not work:

Run[ InputForm[ folderName<>"\\"<>exeName ], "\"OK\"" ];

What I am trying to do in the 2nd example is pass "OK" (with the quotes)
as the first argument to the C program. This is needed, because this
argument will have spaces in it, so it must be wrapped in quotes to be
passed as a single argument.

The first command passed to Run[] is a directory name (with spaces) with
an .exe name concatenated on the end. This first command is surrounded
in quotes, and this works just fine. But the minute I add quotes the 2nd
argument, it seems to be ignoring the quotes around the first command;
It hits a space in the first command and spits out an unrecognized error.

This is odd because the output provided by InputForm[] is correct. If I
type the output directly in the DOS command window, it works as it's
supposed to, but not so in Mathematica.

An example of the text provided to me by InputForm[] which works
perfectly in the DOS console is:

> "C:\\test dir\\prog.exe" "C:\\arg dir"

What's going on?

Thanks for any help!
_Shyam

Chris Chiasson

unread,
Apr 27, 2006, 5:38:22 AM4/27/06
to
InputForm is a function that affects printing. It does not return a
string. Try leaving it out?

Shyam Guthikonda

unread,
Apr 28, 2006, 6:39:26 AM4/28/06
to
Chris Chiasson wrote:
> InputForm is a function that affects printing. It does not return a
> string. Try leaving it out
Nope, I've tried it by manually entering both strings. I've tried
putting them as a single parameter in Run[] separated by a space. I've
tried putting them in 2 parameters in Run[], allowing Run[] to add the
space. As soon as I add even one \" to the 2nd parameter the same
behavior occurs.

Quite odd...

_Shyam

Chris Chiasson

unread,
Apr 28, 2006, 6:59:50 AM4/28/06
to
If you would like to, send your notebook to me and I will take a look
at it. In the past, I have created a Mathematica script that
repeatedly runs an executable to collect data - so I have some idea of
what to do.


--
http://chris.chiasson.name/

Chris Chiasson

unread,
Apr 28, 2006, 7:00:50 AM4/28/06
to
Dear Shyam Guthikonda, (cool name. what country are you from? I'm from the USA)

Your notebook is a little confusing to me, so I erased it and rewrote
it. Also, I haven't yet run your executable. I did make a bat file
with a similar name and tested that. I suspect your program might be
changing its own exit status to 1 after being called correctly - it's
hard to say because I don't know if your program pauses for user
input.

Take a look at the notebook and batch file.

(you're looking for mg66048.* and finalproject.bat)

http://chris.chiasson.name/Mathematica/

or just have the server guess for you

http://chris.chiasson.name/Mathematica/mg66048

Email if you need help. Good day.

On 4/27/06, Shyam Guthikonda <shya...@gmail.com> wrote:

> I created a small example notebook to show the problem. I uploaded
> everything to my webspace. Download it here:
> http://www.shyammichael.com/runProblem.zip
>
> I included the .exe. I put comments in each notebook cell showing the
> problem. Run it from top down.
>
> Thanks for taking the time to look at this. I've very interested to hear
> what the problem might be.
>
> _Shyam


--
http://chris.chiasson.name/

Shyam Guthikonda

unread,
Apr 28, 2006, 7:03:52 AM4/28/06
to

Shyam Guthikonda

unread,
Apr 29, 2006, 4:15:49 AM4/29/06
to
Chris -

I really appreciate you taking the time to help me out. I'm glad you
enjoy my name - I'm from Ohio (exciting!). This really isn't a huge deal
- don't spend too much time on this. I am thinking it may be a bug in Run[].

Here is a screenshot of my run of your notebook (all files are in the
same directory). The batch file does not execute, and so it is returning 1:

http://www.shyammichael.com/screenshot_000.jpg

It works fine on your machine, because your directories do not have
spaces in their names. In order to run this successfully on my machine,
I must surround the first argument in " ":

http://www.shyammichael.com/screenshot_001.jpg

With these modifications, the .bat is executing (Run[] returns 0).

Imagine now, that instead of passing the parameters "hi" and "up" as two
parameters, you want to pass "hi up" as a single parameter (in my case,
this is a directory with spaces). In order to pass "hi up" as a single
parameter, you need to surround the string in " ", so that the space is
ignored. This is where Run[] breaks - when you are trying to add these "
" to the 2nd parameter.

i.e. This should work (but it doesn't):
Run["\""<>ToFileName[thisdir, executable]<>"\"", "\"hi up\""]

which should pass this to the command line (typing this directly into
the command line works):
"C:\theDirectory\finalproject.bat" "hi up"

_Shyam


Chris Chiasson wrote:
> Dear Shyam Guthikonda, (cool name. what country are you from? I'm from the USA)
>
> Your notebook is a little confusing to me, so I erased it and rewrote
> it. Also, I haven't yet run your executable. I did make a bat file
> with a similar name and tested that. I suspect your program might be
> changing its own exit status to 1 after being called correctly - it's
> hard to say because I don't know if your program pauses for user
> input.
>
> Take a look at the notebook and batch file.
>
> (you're looking for mg66048.* and finalproject.bat)
>
> http://chris.chiasson.name/Mathematica/
>
> or just have the server guess for you
>
> http://chris.chiasson.name/Mathematica/mg66048
>
> Email if you need help. Good day.
>

> --
> http://chris.chiasson.name/
>
>
>

Chris Chiasson

unread,
Apr 29, 2006, 4:20:54 AM4/29/06
to
Shyam,

After looking at your comments and making some additions to my
notebooks, I concur with your assessment; I believe there are problems
with space handling in Run.

Here are some examples:
http://chris.chiasson.name/Mathematica/mg66048
http://chris.chiasson.name/Mathematica/mg66048_with_space_in_path

For others, note that an exit error level of zero indicates success,
while an exit error of 1 indicates failure.

If you don't have a premier support account, send me a separate
message and I will file a bug report.

Regards,


--
http://chris.chiasson.name/

Chris Chiasson

unread,
Apr 30, 2006, 4:45:48 AM4/30/06
to
If one has Firefox (and the appropriate free MIT MathML fonts package),
one may notice that

http://chris.chiasson.name/Mathematica/mg66048.xhtml

seems to have no extra space in the second argument of the last two
commands, when it's html brother clearly shows the space

http://chris.chiasson.name/Mathematica/mg66048.html

Could this be chalked up to poor Firefox MathML rendering? No, because
the extra space isn't even present in the markup source.

Chris Chiasson

unread,
May 22, 2006, 6:23:13 PM5/22/06
to
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.
sup...@wolfram.com

Chris Chiasson

unread,
Feb 21, 2007, 6:08:34 AM2/21/07
to
I believe I figured out what happened to the Run command on Windows
and why it sometimes requires an extra set of quotation marks. The
reason is given directly in the output of the help command. Just type

C:\>help cmd

in a DOS box. After the description of the command line switches,
there are two paragraphs and a numbered list. Read the second
paragraph and the numbered list. Also, read the description for the /S
command line switch.

It should then be plain what cmd is doing. cmd is stripping the outer
quotation marks and then processing the command.

For instance, this command works well from a regular command line:

C:\>"C:\Program Files\test.bat" "hi up"

However, if one isn't mindful of the rules above, the following
command might be expected to work:

C:\>cmd /c "C:\Program Files\test.bat" "hi up"

However, according to the processing rules given in the help output,
the first and last quotation marks are stripped, leading to the error:

'C:\Program' is not recognized as an internal or external command,


operable program or batch file.

To avoid this behavior, the /s switch can be fed to cmd and the
argument to cmd can always be quoted:

C:\>cmd /s /c ""C:\Program Files\test.bat" "hi up""

Anyway, I believe the failure to add the outer quotation marks and the
/s switch is a problem with Mathematica, and that the run command
should be altered appropriately in the next version.

For those that do not want to wait, Robby Villegas' trap method works
quite well for overloading Run to always add outer quotation marks
(but you won't be able to add the /s switch, so things may not always
work out properly):

Unprotect@Run;
Update@Run;
$TrapRun=True
Run[args__]/;$TrapRun:=
Block[{$TrapRun=False},
Run["\""<>StringJoin@
BoxForm`Intercalate[ToString[#,InputForm]&/@{args}," "]<>"\""]];
Update@Run;
Protect@Run;

P.S. Does anyone know why Update is sometimes needed when unprotecting
variables? I just add the statements out of habit right now.


--
http://chris.chiasson.name/

Chris Chiasson

unread,
Feb 21, 2007, 6:09:39 AM2/21/07
to
Also, here are the contents of the four line test.bat file I used:

@echo off
echo %1
echo %2
pause


--
http://chris.chiasson.name/

Reply all
Reply to author
Forward
0 new messages