Have been banging my head on this. I have not found a way of executing
a file that has parentheses in its name on Windows.
Say the file is "test.bat" and it lives in "c:\Tcl\bin\a(b)". It
contains: echo Hello
exec c:/Tcl/bin/a\(b\)/test.bat
'c:\Tcl\bin\a' is not recognized as an internal or external command,
operable program or batch file.
set f [open |c:/Tcl/bin/a(b)/test.bat] ; close $f
'c:\Tcl\bin\a' is not recognized as an internal or external command,
operable program or batch file.
set f [open |"c:/Tcl/bin/a(b)/test.bat"]; close $f
'c:\Tcl\bin\a' is not recognized as an internal or external command,
operable program or batch file.
exec {"c:/Tcl/bin/a(b)/test.bat"}
couldn't execute ""c:\Tcl\bin\a(b)\test.bat"": no such file or
directory
The weirdest of all:
cd c:/Tcl/bin/a(b)/
exec test.bat
'C:\Tcl\bin\a' is not recognized as an internal or external command,
operable program or batch file.
>From the Windows command line:
C:\Documents and Settings\user\Desktop>c:\Tcl\bin\a(b)\test.bat
'c:\Tcl\bin\a' is not recognized as an internal or external command,
operable program or batch file.
But if we quote it:
C:\Documents and Settings\user\Desktop>"c:\Tcl\bin\a(b)\test.bat"
C:\Documents and Settings\user\Desktop>echo Hello
Hello
Any ideas? I am going crazy over this. This comes in part from people
installing programs on c:\Program Files (x64) on 64bit versions of
Windows
Thanks in advance for any insight you can provide
Daniel
This sounds as if it is the windows command line which has problems
here understanding its own file system.
exec \"c:/Tcl/bin/a\(b\)/test.bat\"
(yes, make the double quotes part of the program name), or even
exec cmd /c \"c:/Tcl/bin/a\(b\)/test.bat\"
?
R'
Any luck with the following?
% exec [file native C:/Tcl/bin/a(b)/test.bat]
exec cmd /c \"c:/Tcl/bin/a\(b\)/test.bat\"
'\"c:/Tcl/bin/a(b)/test.bat\"' is not recognized as an internal or
external command,
operable program or batch file.
exec \"c:/Tcl/bin/a\(b\)/test.bat\"
couldn't execute ""c:\Tcl\bin\a(b)\test.bat"": no such file or
directory
It is very frustrating. I have also tried single-quotes, multiple
backslashes, file attributes -shortname, etc. and no luck
exec [file native C:/Tcl/bin/a(b)/test.bat]
'C:\Tcl\bin\a' is not recognized as an internal or external command,
operable program or batch file.
exec [file native C:/Tcl/bin/a(b)/test.bat]
'C:\Tcl\bin\a' is not recognized as an internal or external command,
operable program or batch file.
Thanks for your help though
>
> Unfortunately, none of those work...
>
> exec cmd /c \"c:/Tcl/bin/a\(b\)/test.bat\"
> '\"c:/Tcl/bin/a(b)/test.bat\"' is not recognized as an internal or
> external command,
> operable program or batch file.
>
> exec \"c:/Tcl/bin/a\(b\)/test.bat\"
> couldn't execute ""c:\Tcl\bin\a(b)\test.bat"": no such file or
> directory
>
> It is very frustrating. I have also tried single-quotes, multiple
> backslashes, file attributes -shortname, etc. and no luck
>
Is the directory with ()s a Microsoft invention? If so, Microsoft seems
to shot themselves (fatally?) in the foot...
Is this a *production* release of MS-Windows? Or a Beta release? Maybe
someone should let Microsoft know about this. Since things seem broken
from cmd.exe / command.com, this means other 'scripting' code (eg VB)
will have this problem too.
>
> Ralf Fassel wrote:
> > * joi...@yahoo.com
> > | exec c:/Tcl/bin/a\(b\)/test.bat
> > | 'c:\Tcl\bin\a' is not recognized as an internal or external command,
> > | operable program or batch file.
> > --<snip-snip>--
> > | >From the Windows command line:
> > |
> > | C:\Documents and Settings\user\Desktop>c:\Tcl\bin\a(b)\test.bat
> > | 'c:\Tcl\bin\a' is not recognized as an internal or external command,
> > | operable program or batch file.
> >
> > This sounds as if it is the windows command line which has problems
> > here understanding its own file system.
> >
> > exec \"c:/Tcl/bin/a\(b\)/test.bat\"
> >
> > (yes, make the double quotes part of the program name), or even
> >
> > exec cmd /c \"c:/Tcl/bin/a\(b\)/test.bat\"
> >
> > ?
> > R'
>
>
--
Robert Heller -- 978-544-6933
Deepwoods Software -- Linux Installation and Administration
http://www.deepsoft.com/ -- Web Hosting, with CGI and Database
hel...@deepsoft.com -- Contract Programming: C/C++, Tcl/Tk
It's actually ``ok'' from cmd.exe. "cmd /?" has a little
note about special characters and quoting. OTOH, I have no
idea why this works. It just happens that I've run into
something similar in the past...
C:\Documents and Settings\wl>cmd /c c:\tcl\a(b)\f.bat
'c:\tcl\a' is not recognized as an internal or external command,
operable program or batch file.
C:\Documents and Settings\wl>cmd /c "c:\tcl\a(b)\f.bat"
'c:\tcl\a' is not recognized as an internal or external command,
operable program or batch file.
C:\Documents and Settings\wl>cmd /c c:\tcl\a"("b")"\f.bat
hey hey
C:\Documents and Settings\wl>cmd /c "c:\tcl\a"(b)"\f.bat"
hey hey
C:\Documents and Settings\wl>cmd /c c:\tcl\a"(b)"\f.bat
hey hey
C:\Documents and Settings\wl>tclsh
% exec cmd /c {c:\tcl\a"("b")"\f.bat}
The system cannot find the path specified.
% exec cmd /c {"c:\tcl\a"(b)"\f.bat"}
'\"c:\tcl\a\"' is not recognized as an internal or external command,
operable program or batch file.
% exec cmd /c {c:\tcl\a"(b)"\f.bat}
The system cannot find the path specified.
No idea how CreateProcess handles these warts...
--
WL
real mail: wliao at sdf loSnPesAtarM org
(remove the uppercase letters...)
Maybe any of the suggestions on http://wiki.tcl.tk/16336 will offer a
solution:
For example:
package require twapi
interp alias {} twexec {} ::twapi::create_process {} -showwindow hidden
-cmdline
twexec {"C:\Tcl\bin\a(b)\test.bat"}
test
Mark
Daniel writes:
> exec c:/Tcl/bin/a\(b\)/test.bat
> 'c:\Tcl\bin\a' is not recognized as an internal or external command,
> operable program or batch file.
>
> [...]
>
> From the Windows command line:
>
> C:\Documents and Settings\user\Desktop>c:\Tcl\bin\a(b)\test.bat
> 'c:\Tcl\bin\a' is not recognized as an internal or external command,
> operable program or batch file.
>
> But if we quote it:
>
> C:\Documents and Settings\user\Desktop>"c:\Tcl\bin\a(b)\test.bat"
>
> C:\Documents and Settings\user\Desktop>echo Hello
> Hello
In a previous discussion Cameron Laird suggested to use [exec <<] as
in:
exec $::env(COMSPEC) << {"c:\Tcl\bin\a(b)\test.bat"}
Of course in real applications you want to construct the string
dynamically. The main point is that if you can make CMD.EXE do what
you want, than you can use that facility from Tcl by piping the exact
syntax into CMD.EXE.
benny
Thanks, this may be what I am looking for.
But how do I get the stdout / stderr from the process?
I took a look at the examples at http://twapi.sourceforge.net/ and
could not figure it out. I get the process id and with -returnhandles
1, I can get the handle, but I dont know how to translate that into
channels I can read/write from Tcl.
I tried to use
get_tcl_channel_handle stdout read
get_tcl_channel_handle stdin write
to get a handle out of stdin, stdout and pass it in -stdhandles to the
process, but always returns with something similar to:
Error getting channel handle
while executing
"Tcl_GetChannelHandle $chan $direction"
(procedure "::twapi::get_tcl_channel_handle" line 3)
invoked from within
"::twapi::get_tcl_channel_handle stdin write "
("uplevel" body line 1)
invoked from within
"uplevel #0 {::twapi::get_tcl_channel_handle stdin write }"
As already I mentioned on the wiki page http://wiki.tcl.tk/16336 I
don't know of a way to get stdout and stderr outputs using twapi. If
you really need those outputs I can see the following possible ways of
action:
1) Ask the TWAPI author if it is possible
2) Use the << redirect to cmd.exe also mentioned on the wiki page
3) Patch Tcl with the patch at
http://marknet.tk/downloads/exec-quote.patch to make exec support the
-noquote option, which is also described at the wiki.
If you have any luck getting to the stdout and stderr output using
TWAPI please let the NG know or add it to the wiki page as I would be
very interested in that.
Mark
Just curious why you are using that kind of construct?
Robert
Unfortunately, this is the default in new versions of windows 64bit:
Q. Why do some of my programs install into the Program Files Directory,
and others into the Program Files (X86) directory?
A. Windows XP Professional x64 Edition redirects the \Program Files
directory for all programs that are 32-bit during the installation to
the \Program Files(x86) directory. Programs that 64-bit are installed
into the \Program Files directory.
(from http://www.microsoft.com/windowsxp/using/64bit/russel_x64faq.mspx)
I'm not sure how you would go about creating a stdin and stdout for
wish. I tried a quick perusal of the man pages but it wasn't obvious,
at least to me.
/Ashok
set token [open temp.bat w]
puts $token {"c:\Tcl\bin\a(b)\test.bat"}
close $token
exec temp.bat
file delete temp.bat
But somehow they exist, if I do in wish:
fconfigure stdin
I get
-blocking 1 -buffering none -buffersize 4096 -encoding utf-8 -eofchar
{} -translation lf
Maybe they are some kind of pseudo-channel of sorts
Users like to do that sort of thing. They don't care how easy (or not)
it is to administer; they just like being able to put notes into paths
like that. They also like to put just about every other (non-control)
character you can think of in too.
The real question is why cmd.exe has to insist on horking over this. But
that's outside Tcl's terms of reference. :-\
Donal.
CreateProcess is broken when it comes to handling double quotes in
command line arguments. Also, using the exec() family of system calls
you can construct command line arguments which will simply not make it
into the called program but are lost somewhere in the bit bucket.
I remember having struggled with this some time ago when the Cygwin
shell did not show the expected results when calling it with \" on the
commandline (the double quote was part of the argument). In certain
combinations, the double quote never arrived in the called program but
was interpreted by the OS in some way.
Best bet for the OP is to write some intermediate helper script in
some 'unsuspicious' directory and call that instead.
R'
It seems to me that CreateProcess simply passes its command to cmd.exe
somehow (maybe using HKEY_CLASSES_ROOT) and that error is actually
printed by cmd.exe. For example:
#include <stdio.h>
#include <process.h>
int main()
{
spawnlp(P_WAIT, "a(b)\\1.cmd", NULL);
return 0;
}
Will produce:
'a' is not recognized as an internal or external command,
operable program or batch file.
This error is printed by cmd.exe, it is the same as executing "cmd.exe
/c a(b)\1.cmd". Now the interesting part is that when you write
commands in command line (cmd.exe and then typing commands) you are
forced to write:
C:\>"a(b)\1.cmd"
Hello!
However, when using it with cmd.exe it might surprise you:
cmd /c a(b)\1.cmd -> error
cmd /c "a(b)\1.cmd" -> error
cmd /c ""a(b)\1.cmd"" -> success!!!
Apparently it is only because of such strange quoting rules. This never
happens with .exe files, btw, because they are directly executed and
command is never passed to cmd.exe. Summarizing it we *could* come up
with this:
exec cmd /c {"a(b)\\1.cmd"}
HOWEVER, tcl here does its own magic by transforming command into cmd
/c "\"a(b)\\1.cmd\"", because quotation mark is a quotable symbol and
it seems only cmd.exe has such a strange quotation rule here, i.e. it
doesn't follow standard. Because you can't disable exec's quoting and
because cmd.exe has this horrible bug I don't think it is possible
using core tcl.
One soluting might be writing an extension that would execute batch
files as follows:
spawnlp(P_WAIT, "cmd.exe", "/c \"\"a(b)\\1.cmd\"\"", NULL);
This is because spawnlp is ms c runtime has another bug and does no
quoting at all (it just concatenates its arguments with blank space).
And using critcl extension it is as simple as writing a new command:
package require critcl
critcl::ccode {
#include <stdio.h>
#include <process.h>
}
critcl::cproc cmdexec {char* command} int {
return spawnlp(P_WAIT, "cmd.exe", "/c", command, NULL);
}
Now you could you it as this:
cmdexec {""a(b)/1.cmd"" some parameters go here}
But please note that this approach is not portable and can be used only
for Windows with mingw compiler installed.
Or cd to the directory with the parens, invoke the command, and cd back.
--
Darren New / San Diego, CA, USA (PST)
Just because you find out you are
telepathic, don't let it go to your head.
xyz
Copy of xyz
Copy (2) of xyz
They've been doing this since before Macs had directories. :-)
That's inherently multi-thread unsafe.
--
| Don Porter Mathematical and Computational Sciences Division |
| donald...@nist.gov Information Technology Laboratory |
| http://math.nist.gov/~DPorter/ NIST |
|______________________________________________________________________|
Yes but...I always rename that. Maybe that is why I "think" I have
never seen that. : )
Robert
Thanks to everybody who responded to the thread. After a lot of trial
and error, this was the only pure-tcl approach that worked.
I had a similar problem a while ago with exec, and that's how I worked
around it.