"C:\Program Files\test.bat" "C:\Program Files\runFile.txt" 8
set batFile {C:/Program Files/test.bat}
set runFile {C:/Program Files/runFile.txt}
set N 8
set command [concat \"$batFile\" \"$runFile\" $N]
exec {*}$command
On 2/20/2024 2:49 PM, Jacob wrote:
set batFile {C:/Program Files/test.bat}
set runFile {C:/Program Files/runFile.txt}
set N 8
set command [concat \"$batFile\" \"$runFile\" $N]
exec {*}$command
Concat flattens the arguments you provide, and when the exec gets it, it looks for the first item as command name, which would be C:/Program.
You want to try this instead:
set command [list \"$batFile\" \"$runFile\" $N]
On 2/20/2024 12:17 PM, saitology9 wrote:
On 2/20/2024 2:49 PM, Jacob wrote:
set batFile {C:/Program Files/test.bat}
set runFile {C:/Program Files/runFile.txt}
set N 8
set command [concat \"$batFile\" \"$runFile\" $N]
exec {*}$command
Concat flattens the arguments you provide, and when the exec gets it, it
looks for the first item as command name, which would be C:/Program.
You want to try this instead:
set command [list \"$batFile\" \"$runFile\" $N]
Thanks for your suggestion. I actually have tried that as well, and get
the following error:
couldn't execute ""C:/Program Files/test.bat"": No error
Jacob <JacobLambeth@clevelandgolf.com> wrote:
On 2/20/2024 12:17 PM, saitology9 wrote:
On 2/20/2024 2:49 PM, Jacob wrote:
set batFile {C:/Program Files/test.bat}
set runFile {C:/Program Files/runFile.txt}
set N 8
set command [concat \"$batFile\" \"$runFile\" $N]
exec {*}$command
Concat flattens the arguments you provide, and when the exec gets it, it >>> looks for the first item as command name, which would be C:/Program.
You want to try this instead:
set command [list \"$batFile\" \"$runFile\" $N]
Thanks for your suggestion. I actually have tried that as well, and get
the following error:
couldn't execute ""C:/Program Files/test.bat"": No error
The quotes are unnecessary. Remove them.
set command [list $batFile $runFile $N]
On 2/20/2024 1:33 PM, Anonymous wrote:
Jacob <JacobLambeth@clevelandgolf.com> wrote:
On 2/20/2024 12:17 PM, saitology9 wrote:
On 2/20/2024 2:49 PM, Jacob wrote:
set batFile {C:/Program Files/test.bat}
set runFile {C:/Program Files/runFile.txt}
set N 8
set command [concat \"$batFile\" \"$runFile\" $N]
exec {*}$command
Concat flattens the arguments you provide, and when the exec gets it, it >>>> looks for the first item as command name, which would be C:/Program.
You want to try this instead:
set command [list \"$batFile\" \"$runFile\" $N]
Thanks for your suggestion. I actually have tried that as well, and get
the following error:
couldn't execute ""C:/Program Files/test.bat"": No error
The quotes are unnecessary. Remove them.
set command [list $batFile $runFile $N]
The problem appears to be when you have spaces in the path to the first parameter (the file to run/execute).
I can get it to work, but only by doing a
cd [file dirname $batFile]
and then only using the filename portion of batFile on the command line.
I believe this is likely a problem with [exec] as I recall a prior discussion on this a few years back.
Hello,
I am trying to execute a bat file that takes in a few arguments. From Windows command line, this works as intended:
"C:\Program Files\test.bat" "C:\Program Files\runFile.txt" 8
The tcl code looks like this:
set batFile {C:/Program Files/test.bat}
set runFile {C:/Program Files/runFile.txt}
set N 8
set command [concat \"$batFile\" \"$runFile\" $N]
exec {*}$command
Unless I'm missing something, this same process works fine for exe
files. With the batch file, it appears to fail due to the spaces in the batch filepath. Any suggestions? I see online some suggestions to use auto_execok but I can't really figure out how to apply it in this scenario.
Thanks,
Jacob
Jacob <JacobLambeth@clevelandgolf.com> wrote:
Hello,
I am trying to execute a bat file that takes in a few arguments. From
Windows command line, this works as intended:
"C:\Program Files\test.bat" "C:\Program Files\runFile.txt" 8
The tcl code looks like this:
set batFile {C:/Program Files/test.bat}
set runFile {C:/Program Files/runFile.txt}
set N 8
set command [concat \"$batFile\" \"$runFile\" $N]
exec {*}$command
Unless I'm missing something, this same process works fine for exe
files. With the batch file, it appears to fail due to the spaces in the
batch filepath. Any suggestions? I see online some suggestions to use
auto_execok but I can't really figure out how to apply it in this scenario. >>
Thanks,
Jacob
et99 showed the way to "run" a bat file on windows.
The reason you are having trouble is that windows has no notion of
"script" files like Unix/Linux systems do (i.e., there is nothing
equivalent to the #!/path/to/interpreter feature of Unix/Linux in
windows)
So you either have to launch the proper interpreter, passing it the bat
file as a parameter (as et99 showed) or you have to use auto_execok to
obtain the right "invocation" to run the batch file (and auto_execok
should give back something similar to what et99 showed).
On Unix/Linux systems script files are first class "executables" just
the same as an ELF binary executable for the host CPU. Under windows,
script files (and bat files) are truly second class citizens, at best.
exec {*}[auto_execok start] {} /D [file dirname $batFile] [file tail $batFile] $runFile $N
On 2/20/2024 10:03 PM, et99 wrote:
exec {*}[auto_execok start] {} /D [file dirname $batFile] [file tail
$batFile] $runFile $N
Thank you for your responses. This method does in fact work. It is definitely more complicated than I would like. I explored solutions in Python (subprocess.Popen) and Matlab (system) and they are much cleaner. Perhaps they just have the same stuff already being done behind the scenes.
* Jacob <JacobLambeth@clevelandgolf.com>
| I am trying to execute a bat file that takes in a few arguments. From
| Windows command line, this works as intended:
| >"C:\Program Files\test.bat" "C:\Program Files\runFile.txt" 8
| The tcl code looks like this:
| set batFile {C:/Program Files/test.bat}
| set runFile {C:/Program Files/runFile.txt}
| set N 8
| set command [concat \"$batFile\" \"$runFile\" $N]
| exec {*}$command
| Unless I'm missing something, this same process works fine for exe
| files. With the batch file, it appears to fail due to the spaces in
| the batch filepath. Any suggestions?
IMHO you should just use [list] instead of [concat] to construct the
command and exec the .bat command directly, not via auto_execok, which
only introduces more quoting issues.
This works for me:
set batFile {C:/Program Files/test.bat}
set runFile {C:/Program Files/runFile.txt}
set N 8
set command [list $batFile $runFile $N]
exec {*}$command
TCL on Windows can 'exec' .bat files just fine (cf. TCL source code).
HTH
R'
Am 21.02.2024 um 16:02 schrieb Jacob:
On 2/20/2024 10:03 PM, et99 wrote:
exec {*}[auto_execok start] {} /D [file dirname $batFile] [file tail
$batFile] $runFile $N
Thank you for your responses. This method does in fact work. It is
definitely more complicated than I would like. I explored solutions in
Python (subprocess.Popen) and Matlab (system) and they are much
cleaner. Perhaps they just have the same stuff already being done
behind the scenes.
IMHO, the following should do the job:
exec {*}[auto_execok start] "" [file nativename $batFile] [file
nativename $runFile] $N
Remark the empty pair of quotes as first argument of the start.exe
command. This is to avoid, that the batfile name is taken as window title.
Try "help start" in a dos box.
Remark also, that there are a couple of bugs here and 8.6.14 will again change the behaviour.
Take care,
Harald
Hello,
I am trying to execute a bat file that takes in a few arguments. From Windows command line, this works as intended:
"C:\Program Files\test.bat" "C:\Program Files\runFile.txt" 8
The tcl code looks like this:
set batFile {C:/Program Files/test.bat}
set runFile {C:/Program Files/runFile.txt}
set N 8
set command [concat \"$batFile\" \"$runFile\" $N]
exec {*}$command
Unless I'm missing something, this same process works fine for exe
files. With the batch file, it appears to fail due to the spaces in the batch filepath. Any suggestions? I see online some suggestions to use auto_execok but I can't really figure out how to apply it in this scenario.
Thanks,
Jacob
On 2/21/2024 8:58 AM, Ralf Fassel wrote:
* Jacob <JacobLambeth@clevelandgolf.com>
| I am trying to execute a bat file that takes in a few arguments. From
| Windows command line, this works as intended:
| >"C:\Program Files\test.bat" "C:\Program Files\runFile.txt" 8
| The tcl code looks like this:
| set batFile {C:/Program Files/test.bat}
| set runFile {C:/Program Files/runFile.txt}
| set N 8
| set command [concat \"$batFile\" \"$runFile\" $N]
| exec {*}$command
| Unless I'm missing something, this same process works fine for exe
| files. With the batch file, it appears to fail due to the spaces in
| the batch filepath. Any suggestions?
IMHO you should just use [list] instead of [concat] to construct the
command and exec the .bat command directly, not via auto_execok, which
only introduces more quoting issues.
This works for me:
set batFile {C:/Program Files/test.bat}
set runFile {C:/Program Files/runFile.txt}
set N 8
set command [list $batFile $runFile $N]
exec {*}$command
TCL on Windows can 'exec' .bat files just fine (cf. TCL source code).
HTH
R'
Ralf,
This was actually the very first thing I tried. After troubleshooting a bit more, it appears to fail when there is a space in $runFile.
-Jacob
cmd.exe /c C:\Program Files\test.bat'C:\Program' is not recognized as an internal or external command,
Am 20.02.24 um 20:49 schrieb Jacob:
Hello,
I am trying to execute a bat file that takes in a few arguments. From Windows command line, this works as intended:
;"C:\Program Files\test.bat" "C:\Program Files\runFile.txt" 8
The tcl code looks like this:
set batFile {C:/Program Files/test.bat}
set runFile {C:/Program Files/runFile.txt}
set N 8
set command [concat \"$batFile\" \"$runFile\" $N]
exec {*}$command
Unless I'm missing something, this same process works fine for exe files. With the batch file, it appears to fail due to the spaces in the batch filepath. Any suggestions? I see online some suggestions to use auto_execok but I can't really figure out how to apply it in this scenario.
Thanks,
Jacob
#! /usr/bin/env tclsh
set batFile "C:/Program Files/test.bat"
set runFile "C:/Program Files/runFile.txt"
set N 8
exec cmd /c start /min "" $batFile $runFile $N
On 2/21/2024 10:39 AM, Jacob wrote:
On 2/21/2024 8:58 AM, Ralf Fassel wrote:
* Jacob <JacobLambeth@clevelandgolf.com>
| I am trying to execute a bat file that takes in a few arguments. From
| Windows command line, this works as intended:
| >"C:\Program Files\test.bat" "C:\Program Files\runFile.txt" 8
| The tcl code looks like this:
| set batFile {C:/Program Files/test.bat}
| set runFile {C:/Program Files/runFile.txt}
| set N 8
| set command [concat \"$batFile\" \"$runFile\" $N]
| exec {*}$command
| Unless I'm missing something, this same process works fine for exe
| files. With the batch file, it appears to fail due to the spaces in
| the batch filepath. Any suggestions?
IMHO you should just use [list] instead of [concat] to construct the
command and exec the .bat command directly, not via auto_execok, which
only introduces more quoting issues.
This works for me:
set batFile {C:/Program Files/test.bat}
set runFile {C:/Program Files/runFile.txt}
set N 8
set command [list $batFile $runFile $N]
exec {*}$command
TCL on Windows can 'exec' .bat files just fine (cf. TCL source code).
HTH
R'
Ralf,
This was actually the very first thing I tried. After troubleshooting
a bit more, it appears to fail when there is a space in $runFile.
-Jacob
Jacob:
Are you certain its the space in runFile? When I try with a batFile that
has no spaces in the path, it works even if runFile has spaces. When
batFile has the spaces is when all the previously suggested solutions
failed for me.
I tried with several versions of tcl, including an 8.6.9 tclkit, 8.6.13 magicsplat, and 9.0b1 all 3 give the same error, which is not coming
from tcl source code, but is the same exact text as this from a cmd
window (and has the back slashes regardless of how I sent them to exec):
cmd.exe /c C:\Program Files\test.bat'C:\Program' is not recognized as an internal or external command,
operable program or batch file.
which is because there's no quotes around the file name. So, somewhere
in the translation, [exec] has stripped them before sending them in.
That is why it works if there are no spaces in the path.
Also, all that auto_execok does is look at the first parameter, which is "start" and generates:
% auto_execok start
C:/Windows/System32/cmd.exe /c start
where (from looking at it's code) it uses:
% set env(COMSPEC)
C:\WINDOWS\system32\cmd.exe
% file attributes $env(COMSPEC) -shortname
C:/Windows/System32/cmd.exe
Yes, it is quite weird. It will work if batFile OR runFile contain no spaces. If both have a space, it fails!
* Jacob <JacobLambeth@clevelandgolf.com>
| On 2/21/2024 8:58 AM, Ralf Fassel wrote:
| > IMHO you should just use [list] instead of [concat] to construct the
| > command and exec the .bat command directly, not via auto_execok, which
| > only introduces more quoting issues.
| > This works for me:
| > set batFile {C:/Program Files/test.bat}
| > set runFile {C:/Program Files/runFile.txt}
| > set N 8
| > set command [list $batFile $runFile $N]
| > exec {*}$command
| > TCL on Windows can 'exec' .bat files just fine (cf. TCL source
| > code).
| Ralf,
| This was actually the very first thing I tried. After troubleshooting
| a bit more, it appears to fail when there is a space in $runFile.
Can you
- tell what 'fail' means in this context:
- TCL fails to execute the batch
- the batch fails to recognize the parameters
- other?
- show the contents of C:/Program Files/test.bat
- show the transcript of the session you tried?
Here's mine:
$ cd C:/Users/ralf/AppData/Local/Temp/foo bar
$ cat xxx.bat
@echo off
REM xxx.bat
echo this is xxx.bat
echo arguments /%1/ /%2/ /%3/
$ tclsh
% pwd
C:/Users/ralf/AppData/Local/Temp/foo bar
% set cmd [list [file join [pwd] xxx.bat] arg1 "arg2 with space" arg3]
{C:/Users/ralf/AppData/Local/Temp/foo bar/xxx.bat} arg1 {arg2 with space} arg3
% exec {*}$cmd
this is xxx.bat
arguments /arg1/ /"arg2 with space"/ /arg3/
HTH
R'
* Jacob <JacobLambeth@clevelandgolf.com>
| Sure, here is my bat file (test.bat):
| @echo off
| (for %%a in (%*) do (
| echo %%a
| ))
--<snip-snip>--
Your test 1-3 show what I would expect.
| #Test4:
| set batFile {C:\batTest\bat test\test.bat}
| set arg1 {arg with spaces}
| set arg2 8
| set command [list $batFile $arg1 $arg2]
| exec {*}$command
| Output:
| 'C:\batTest\bat' is not recognized as an internal or external command,
| operable program or batch file.
Interesting. I get:
% set batFile {C:\batTest\bat test\test.bat}
C:\batTest\bat test\test.bat
% set arg1 {arg with spaces}
arg with spaces
% set arg2 8
8
% set command [list $batFile $arg1 $arg2]
{C:\batTest\bat test\test.bat} {arg with spaces} 8
% exec {*}$command
this is test.bat
"arg with spaces"
8
%
I.e. I get the expected result.
I had modified the test.bat with an additional first line
echo this is test.bat
to show whether I did get there at all, but it makes no difference if I
take that out again (I still get the expectzed result). I wonder
whether the message you see comes from the script (= Windows) or from TCL
(= tkcon trying to exec something).
If you add a first line to the test.bat script, do you get there, or
does tkcon bail out before it can execute the test.bat?
@echo off
echo this is test.bat
(for %%a in (%*) do (
echo %%a
))
| I am running Tcl 8.6.13 via Magic Splat in tkcon shell.
I'm running a self-compiled 8.6.13...
R'
Ralf,
Sure, here is my bat file (test.bat):
@echo off
(for %%a in (%*) do (
echo %%a
))
I have placed the file in 2 locations:
"C:\batTest\bat test\test.bat"
"C:\batTest\test.bat"
On 2/22/2024 9:30 AM, Jacob wrote:
Ralf,
Sure, here is my bat file (test.bat):
@echo off
(for %%a in (%*) do (
echo %%a
))
I have placed the file in 2 locations:
"C:\batTest\bat test\test.bat"
"C:\batTest\test.bat"
Exec behavior may vary a bit depending on the platform, like using the right quotation to mark individual arguments to the command itself, but nevertheless this is interesting.
With a wish shell or from tkcon, there seems to be no way to properly escape an argument containing spaces, to the command being invoked, without breaking the exec command.
However, from a plain tclsh, everything works fine. You can escape arguments with spaces by enclosing them in double-quotes, which Windows accepts fine.
# i added a line to the bat file
% exec $bat
done...
% exec $bat 1 2 3
1
2
3
done...
% exec $bat 1 2 3 "Hello there"
1
2
3
"Hello there"
done...
On 2/22/2024 9:43 AM, saitology9 wrote:
On 2/22/2024 9:30 AM, Jacob wrote:
;
Ralf,
;
Sure, here is my bat file (test.bat):
;
@echo off
(for %%a in (%*) do (
; echo %%a
))
;
I have placed the file in 2 locations:
"C:\batTest\bat test\test.bat"
"C:\batTest\test.bat"
;
Exec behavior may vary a bit depending on the platform, like using the right quotation to mark individual arguments to the command itself, but nevertheless this is interesting.
With a wish shell or from tkcon, there seems to be no way to properly escape an argument containing spaces, to the command being invoked, without breaking the exec command.
However, from a plain tclsh, everything works fine. You can escape arguments with spaces by enclosing them in double-quotes, which Windows accepts fine.
# i added a line to the bat file
% exec $bat
done...
% exec $bat 1 2 3
1
2
3
done...
% exec $bat 1 2 3 "Hello there"
1
2
3
"Hello there"
done...
I think some of these different results might also depend on the value of tcl_interactive.
When it's set to 1, I can type (into a wish console):
% start wish "C:/Users/et/Desktop/New folder/testargs.bat" one two "thr ee"
and this works. But with exec it fails:
% exec "C:/Users/et/Desktop/New folder/testargs.bat" one two "thr ee" 'C:\Users\et\Desktop\New' is not recognized as an internal or external command,
operable program or batch file.
but if "thr ee" is "three" it again works.
I searched the tcl source and that message is nowhere to be found, I'm pretty certain it comes from windows, perhaps from some kind of error code to text windows call.
I think a ticket is in order.
On 2/22/2024 12:51 PM, et99 wrote:
On 2/22/2024 9:43 AM, saitology9 wrote:
On 2/22/2024 9:30 AM, Jacob wrote:
;
Ralf,
;
Sure, here is my bat file (test.bat):
;
@echo off
(for %%a in (%*) do (
; echo %%a
))
;
I have placed the file in 2 locations:
"C:\batTest\bat test\test.bat"
"C:\batTest\test.bat"
;
Exec behavior may vary a bit depending on the platform, like using
the right quotation to mark individual arguments to the command
itself, but nevertheless this is interesting.
With a wish shell or from tkcon, there seems to be no way to properly
escape an argument containing spaces, to the command being invoked,
without breaking the exec command.
However, from a plain tclsh, everything works fine. You can escape
arguments with spaces by enclosing them in double-quotes, which
Windows accepts fine.
# i added a line to the bat file
% exec $bat
done...
% exec $bat 1 2 3
1
2
3
done...
% exec $bat 1 2 3 "Hello there"
1
2
3
"Hello there"
done...
I think some of these different results might also depend on the value
of tcl_interactive.
When it's set to 1, I can type (into a wish console):
% start wish "C:/Users/et/Desktop/New folder/testargs.bat" one two
"thr ee"
and this works. But with exec it fails:
% exec "C:/Users/et/Desktop/New folder/testargs.bat" one two "thr ee"
'C:\Users\et\Desktop\New' is not recognized as an internal or external
command,
operable program or batch file.
but if "thr ee" is "three" it again works.
I searched the tcl source and that message is nowhere to be found, I'm
pretty certain it comes from windows, perhaps from some kind of error
code to text windows call.
I think a ticket is in order.
Oops, this might be working for me because my batch scripts can be
executed either by windows batch, or by running with wish. Sometimes I outsmart myself :)
On 2/22/2024 9:43 AM, saitology9 wrote:
I think some of these different results might also depend on the value
of tcl_interactive.
On 2/22/2024 3:51 PM, et99 wrote:
On 2/22/2024 9:43 AM, saitology9 wrote:
I think some of these different results might also depend on the value of tcl_interactive.
I would suspect that the error is most likely in wish's command line / argument parsing code. It seems to be different from tclsh's version. Tkcon is a red herring here because it relies on wish, so any behavioral difference stemming from wish will also show up in tkcon.
On 2/22/2024 5:47 PM, saitology9 wrote:
On 2/22/2024 3:51 PM, et99 wrote:
On 2/22/2024 9:43 AM, saitology9 wrote:
I think some of these different results might also depend on the value of tcl_interactive.
I would suspect that the error is most likely in wish's command line / argument parsing code. It seems to be different from tclsh's version. Tkcon is a red herring here because it relies on wish, so any behavioral difference stemming from wish will also show up in tkcon.
I took a look at the source code and it seems the key is the functions ApplicationType and then BuildCommandLine in tclWinPipe.c.
These two are called by TclpCreateProcess which has as input effectively a tcl arglist, which comes in as argv, and argv[0] is immediately sent to ApplicationType which returns a value, such as APPL_DOS (for .bat files).
This also converts argv[0] into a full complete path to the executable. In doing this conversion it does some directory searching where it tries the name as is, or then adds .com, .exe, .bat and .cmd in that order trying for a match.
If it is type APPL_DOS for .bat, then the command line is prefixed with the literal string "cmd.exe /c". The command line is built up into cmdLine.
Next, they call BuildCommandLine(execPath, argc, argv, &cmdLine) and this function looks at each arg and handles any escaping and quoting. There's much there I cannot easily follow, other than they continue to build up cmdLine. But it is pretty clear that this is where they should be enclosing the batch file in quotes.
This arg loop treats argv[0] separately, getting it from execPath instead, skipping over the original argv[0], having that been full-path'd, by ApplicationType. So, this arg either starts the command line, or is appended to "cmd.exe /c " and continues to build up cmdLine.
Finally, the actual windows call:
CreateProcessW(NULL, (WCHAR *) Tcl_DStringValue(&cmdLine),...
If I were to try to debug this, I likely would try inserting some printf's there since cmdLine is a regular C string. On linux, I used to simply do an fprintf(stderr,...) and it would output to a terminal windows. I can build tcl9.01 for windows but I don't know how to output debug stuff when the tk console is used. It might work in tclsh, but that isn't where the problem seems to be.
Maybe someone else might want to play with this some more, I'm getting sleepy :)
On 2/22/2024 8:11 PM, et99 wrote:
On 2/22/2024 5:47 PM, saitology9 wrote:
On 2/22/2024 3:51 PM, et99 wrote:
On 2/22/2024 9:43 AM, saitology9 wrote:
I think some of these different results might also depend on the
value of tcl_interactive.
I would suspect that the error is most likely in wish's command line
/ argument parsing code. It seems to be different from tclsh's
version. Tkcon is a red herring here because it relies on wish, so
any behavioral difference stemming from wish will also show up in tkcon. >>>
I took a look at the source code and it seems the key is the functions
ApplicationType and then BuildCommandLine in tclWinPipe.c.
These two are called by TclpCreateProcess which has as input
effectively a tcl arglist, which comes in as argv, and argv[0] is
immediately sent to ApplicationType which returns a value, such as
APPL_DOS (for .bat files).
This also converts argv[0] into a full complete path to the
executable. In doing this conversion it does some directory searching
where it tries the name as is, or then adds .com, .exe, .bat and .cmd
in that order trying for a match.
If it is type APPL_DOS for .bat, then the command line is prefixed
with the literal string "cmd.exe /c". The command line is built up
into cmdLine.
Next, they call BuildCommandLine(execPath, argc, argv, &cmdLine) and
this function looks at each arg and handles any escaping and quoting.
There's much there I cannot easily follow, other than they continue to
build up cmdLine. But it is pretty clear that this is where they
should be enclosing the batch file in quotes.
This arg loop treats argv[0] separately, getting it from execPath
instead, skipping over the original argv[0], having that been
full-path'd, by ApplicationType. So, this arg either starts the
command line, or is appended to "cmd.exe /c " and continues to build
up cmdLine.
Finally, the actual windows call:
CreateProcessW(NULL, (WCHAR *) Tcl_DStringValue(&cmdLine),...
If I were to try to debug this, I likely would try inserting some
printf's there since cmdLine is a regular C string. On linux, I used
to simply do an fprintf(stderr,...) and it would output to a terminal
windows. I can build tcl9.01 for windows but I don't know how to
output debug stuff when the tk console is used. It might work in
tclsh, but that isn't where the problem seems to be.
Maybe someone else might want to play with this some more, I'm getting
sleepy :)
Well, back at it. ... but I think (99.9% sure) I know the problem.
When it's a batch job, i.e. something .bat, wish generates:
cmd.exe /c "pa th\to.bat" "pa th/to.txt" 8
and that fails. If you enter that into a windows cmd window, it also
fails *because* it needs to have another set of quotes around the whole string following the /c.
Changing that in a cmd window to:
cmd.exe /c ""pa th\to.bat" "pa th/to.txt" 8"
and it works.
When the path to the batch file has no spaces, it does not quote that,
*and* will fail if you do add quotes anyway. Now that's really weird,
but in fact I saw something about that in the documentation.
Now, if you use tclsh and exec, it ends up being just this:
"pa th\to.bat" "pa th/to.txt" 8
and that works from tclsh and also in a cmd window.
It's because the call to HasConsole() returns true in tclsh so that the command line is not prefixed with cmd.exe /c
BTW, the cmdLine variable is actually a 16 unicode string and I had to convert it so I could log it to a file.
Here's the key code:
if (HasConsole()) {
createFlags = 0;
} else if (applType == APPL_DOS) {
/*
* Under NT, 16-bit DOS applications will not run unless they can
* be attached to a console. If we are running without a console,
* run the 16-bit program as an normal process inside of a hidden
* console application, and then run that hidden console as a
* detached process.
*/
startInfo.wShowWindow = SW_HIDE;
startInfo.dwFlags |= STARTF_USESHOWWINDOW;
createFlags = CREATE_NEW_CONSOLE;
TclDStringAppendLiteral(&cmdLine, "cmd.exe /c");
} else {
createFlags = DETACHED_PROCESS;
}
BTW, the cmdLine variable is actually a 16 unicode string and I had
to convert it so I could log it to a file.
It might be a tk bug, as wish is only present with tk.
et99 <et99@rocketship1.me> wrote:
BTW, the cmdLine variable is actually a 16 unicode string and I had
to convert it so I could log it to a file.
I think you mean a UTF-16 string. That is the native encoding used by
the NT kernel underlying modern MS windows. When NT was being
developed, UTF-16 was seen as the "be all" encoding. UTF-8
subsequently won out in the end, but NT now has to carry the UTF-16
legacy baggage around.
Harald wrote:
It might be a tk bug, as wish is only present with tk.
It's code that is found in the windows specific code for [exec] in tclWinPipe.c, which is called by both tclsh and wish. The difference
being that the hasconsole() function returns different values for wish
and tclsh. The reason it fails with .bat files is the function ApplicationType returns APPL_DOS because of the file extension:
if ((ext != NULL) &&
(strcasecmp(ext, ".cmd") == 0 || strcasecmp(ext, ".bat") ==
0)) {
applType = APPL_DOS;
break;
}
And then after it gets a fasle from hasconsole(), it tests for APPL_DOS,
and adds the "cmd.exe /c" but doesn't do the quoting right.
This also explains why it doesn't fail with .exe with non-legacy executables. The code actually reads the header's of the files, looking
for some really old "magic numbers" as it calls them to return some
other application types for .exe, but really old executables can still result in APPL_DOS.
I've added my analysis to the bug report.
On 2/23/2024 10:36 AM, Rich wrote:
et99 <et99@rocketship1.me> wrote:
BTW, the cmdLine variable is actually a 16 unicode string and I had
to convert it so I could log it to a file.
I think you mean a UTF-16 string. That is the native encoding used by
the NT kernel underlying modern MS windows. When NT was being
developed, UTF-16 was seen as the "be all" encoding. UTF-8
subsequently won out in the end, but NT now has to carry the UTF-16
legacy baggage around.
Yes, you're right. At first I was only getting the first char C in my logger. That's when I guessed it was 16 bit, with every other byte a 0,
and confirmed that the windows commandline argument was indeed unicode.
Here's my log code, in case anyone else might find it useful for
debugging on windows:
I placed this at the top of the file (a: is my temp ramdisk):
/* -------------- debugging printf to a log file ---------------- */
#include <stdarg.h>
#include <stdlib.h>
void
bugprintf (const char *template, ...)
{
va_list ap;
FILE *io;
io = fopen("a:/log.txt","a");
va_start (ap, template);
vfprintf (io, template, ap);
va_end (ap);
fclose(io);
}
char bug_buffer[1000]; /* for unicode to plain ascii conversion */
Then just before it calls the windows CreateProcessW code:
wcstombs(bug_buffer, (WCHAR *) Tcl_DStringValue(&cmdLine), 999);
bugprintf("pathb = |%s|\n",bug_buffer);
This is apparently enough, as the output was null terminated.
Hi ET99,
great analysis, thank you.
Unfortunately, I can not see new information in the ticket:
https://core.tcl-lang.org/tcl/info/f91ab723f3dfbc0d
Or do you mean your post 2024-02-23 07:34:22 ?
Take care,
Harald
On 2/26/2024 12:58 AM, Harald Oehlmann wrote:
Hi ET99,
great analysis, thank you.
Unfortunately, I can not see new information in the ticket:
https://core.tcl-lang.org/tcl/info/f91ab723f3dfbc0d
Or do you mean your post 2024-02-23 07:34:22 ?
Take care,
Harald
Yes, that was what I added to the ticket.
I probably should have mentioned that my tests, and the code I was referencing was from 9.0b1, since I just now compared tclWinPipe.c from 8.6.13 to 9.0b1 and there is a bit of difference. It hadn't occurred to
me that the code would be different with respect to cmd.exe /c. It
appears that in 8.6.13 there's a test that is removed in 9.0b1:
if (TclWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
And that is what oehhar mentions in the ticket. I can say with
confidence that the 9.0b1 code has the problem, and perhaps because that
was removed.
I didn't hand build and trace 8.6.13, so that might be doing something different. There I was using magicsplat 8.6.13, but also a tclkit 8.6.9
and this might also explain why some of the failures I got were
different than what Jacob was seeing.
Sorry for any confusion I might have caused. I just sent a clarification
to the ticket.
Am 28.02.2024 um 01:48 schrieb et99:
On 2/26/2024 12:58 AM, Harald Oehlmann wrote:
Hi ET99,
great analysis, thank you.
Unfortunately, I can not see new information in the ticket:
https://core.tcl-lang.org/tcl/info/f91ab723f3dfbc0d
Or do you mean your post 2024-02-23 07:34:22 ?
Take care,
Harald
Yes, that was what I added to the ticket.
I probably should have mentioned that my tests, and the code I was referencing was from 9.0b1, since I just now compared tclWinPipe.c from 8.6.13 to 9.0b1 and there is a bit of difference. It hadn't occurred to me that the code would be different with respect to cmd.exe /c. It appears that in 8.6.13 there's a test that is removed in 9.0b1:
if (TclWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
And that is what oehhar mentions in the ticket. I can say with confidence that the 9.0b1 code has the problem, and perhaps because that was removed.
I didn't hand build and trace 8.6.13, so that might be doing something different. There I was using magicsplat 8.6.13, but also a tclkit 8.6.9 and this might also explain why some of the failures I got were different than what Jacob was seeing.
Sorry for any confusion I might have caused. I just sent a clarification to the ticket.
Hi ET99,
no, there is no confusion, no problem. Only confusing code ;-).
It would be great if you could test the two proposed bug branches, if they work for you or not.
Take care,
Harald
On 2/28/2024 12:19 AM, Harald Oehlmann wrote:
Am 28.02.2024 um 01:48 schrieb et99:
On 2/26/2024 12:58 AM, Harald Oehlmann wrote:
Hi ET99,
great analysis, thank you.
Unfortunately, I can not see new information in the ticket:
https://core.tcl-lang.org/tcl/info/f91ab723f3dfbc0d
Or do you mean your post 2024-02-23 07:34:22 ?
Take care,
Harald
Yes, that was what I added to the ticket.
I probably should have mentioned that my tests, and the code I was
referencing was from 9.0b1, since I just now compared tclWinPipe.c
from 8.6.13 to 9.0b1 and there is a bit of difference. It hadn't
occurred to me that the code would be different with respect to
cmd.exe /c. It appears that in 8.6.13 there's a test that is removed
in 9.0b1:
if (TclWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
And that is what oehhar mentions in the ticket. I can say with
confidence that the 9.0b1 code has the problem, and perhaps because
that was removed.
I didn't hand build and trace 8.6.13, so that might be doing
something different. There I was using magicsplat 8.6.13, but also a
tclkit 8.6.9 and this might also explain why some of the failures I
got were different than what Jacob was seeing.
Sorry for any confusion I might have caused. I just sent a
clarification to the ticket.
Hi ET99,
no, there is no confusion, no problem. Only confusing code ;-).
It would be great if you could test the two proposed bug branches, if
they work for you or not.
Take care,
Harald
I could do that but I would need to know how to get the new code. I only just learned how to build from sources on windows. I don't know how the
code management system works. If you could copy out the entire file somewhere with a link, or post it somewhere on the wiki, I could grab it
and do a build. It's win/tclWinPipe.c, correct? I do have a pretty good program for comparing files (beyond compare) so I could see what's different.
-et
Am 28.02.2024 um 20:25 schrieb et99:
On 2/28/2024 12:19 AM, Harald Oehlmann wrote:
Am 28.02.2024 um 01:48 schrieb et99:
On 2/26/2024 12:58 AM, Harald Oehlmann wrote:
Hi ET99,
great analysis, thank you.
Unfortunately, I can not see new information in the ticket:
https://core.tcl-lang.org/tcl/info/f91ab723f3dfbc0d
Or do you mean your post 2024-02-23 07:34:22 ?
Take care,
Harald
Yes, that was what I added to the ticket.
I probably should have mentioned that my tests, and the code I was referencing was from 9.0b1, since I just now compared tclWinPipe.c from 8.6.13 to 9.0b1 and there is a bit of difference. It hadn't occurred to me that the code would be different with respect to cmd.exe /c. It appears that in 8.6.13 there's a test that is removed in 9.0b1:
if (TclWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
And that is what oehhar mentions in the ticket. I can say with confidence that the 9.0b1 code has the problem, and perhaps because that was removed.
I didn't hand build and trace 8.6.13, so that might be doing something different. There I was using magicsplat 8.6.13, but also a tclkit 8.6.9 and this might also explain why some of the failures I got were different than what Jacob was seeing.
Sorry for any confusion I might have caused. I just sent a clarification to the ticket.
Hi ET99,
no, there is no confusion, no problem. Only confusing code ;-).
It would be great if you could test the two proposed bug branches, if they work for you or not.
Take care,
Harald
I could do that but I would need to know how to get the new code. I only just learned how to build from sources on windows. I don't know how the code management system works. If you could copy out the entire file somewhere with a link, or post it somewhere on the wiki, I could grab it and do a build. It's win/tclWinPipe.c, correct? I do have a pretty good program for comparing files (beyond compare) so I could see what's different.
-et
Yes, no problem.
Go to:
https://core.tcl-lang.org/tcl/login
and log in as anonymous with the ASCII-Art password.
Then find the two proposed branches.
You may use the timeline and find the two red colored lines https://core.tcl-lang.org/tcl/timeline
or you go to the ticket:
https://core.tcl-lang.org/tcl/info/f91ab723f3dfbc0d
within the 3rd comment titled:
oehhar added on 2024-02-26 14:09:08:
you find 2 blue links.
If you press on the links, the chckin page opens.
You see the proposed changes as a diff.
To download, look to the 2nd line from the top titled "Downloads".
I would click on "ZIP archive" to download the whole distribution.
Please come back to me in case of any questions.
Thank you and take care,
Harald
On 2/28/2024 11:41 AM, Harald Oehlmann wrote:
Am 28.02.2024 um 20:25 schrieb et99:
On 2/28/2024 12:19 AM, Harald Oehlmann wrote:
Am 28.02.2024 um 01:48 schrieb et99:
On 2/26/2024 12:58 AM, Harald Oehlmann wrote:
Hi ET99,
great analysis, thank you.
Unfortunately, I can not see new information in the ticket:
https://core.tcl-lang.org/tcl/info/f91ab723f3dfbc0d
Or do you mean your post 2024-02-23 07:34:22 ?
Take care,
Harald
Yes, that was what I added to the ticket.
I probably should have mentioned that my tests, and the code I was
referencing was from 9.0b1, since I just now compared tclWinPipe.c
from 8.6.13 to 9.0b1 and there is a bit of difference. It hadn't
occurred to me that the code would be different with respect to
cmd.exe /c. It appears that in 8.6.13 there's a test that is
removed in 9.0b1:
if (TclWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
And that is what oehhar mentions in the ticket. I can say with
confidence that the 9.0b1 code has the problem, and perhaps because >>>>> that was removed.
I didn't hand build and trace 8.6.13, so that might be doing
something different. There I was using magicsplat 8.6.13, but also
a tclkit 8.6.9 and this might also explain why some of the failures >>>>> I got were different than what Jacob was seeing.
Sorry for any confusion I might have caused. I just sent a
clarification to the ticket.
Hi ET99,
no, there is no confusion, no problem. Only confusing code ;-).
It would be great if you could test the two proposed bug branches,
if they work for you or not.
Take care,
Harald
I could do that but I would need to know how to get the new code. I
only just learned how to build from sources on windows. I don't know
how the code management system works. If you could copy out the
entire file somewhere with a link, or post it somewhere on the wiki,
I could grab it and do a build. It's win/tclWinPipe.c, correct? I do
have a pretty good program for comparing files (beyond compare) so I
could see what's different.
-et
Yes, no problem.
Go to:
https://core.tcl-lang.org/tcl/login
and log in as anonymous with the ASCII-Art password.
Then find the two proposed branches.
You may use the timeline and find the two red colored lines
https://core.tcl-lang.org/tcl/timeline
or you go to the ticket:
https://core.tcl-lang.org/tcl/info/f91ab723f3dfbc0d
within the 3rd comment titled:
oehhar added on 2024-02-26 14:09:08:
you find 2 blue links.
If you press on the links, the chckin page opens.
You see the proposed changes as a diff.
To download, look to the 2nd line from the top titled "Downloads".
I would click on "ZIP archive" to download the whole distribution.
Please come back to me in case of any questions.
Thank you and take care,
Harald
I tried to find it but to no avail. I only am really in a position to build 9.0b1. When the next 9.0 beta comes out I can take a look,
assuming the fix will go in there. Sorry.
Am 29.02.2024 um 10:40 schrieb et99:
On 2/28/2024 11:41 AM, Harald Oehlmann wrote:
Am 28.02.2024 um 20:25 schrieb et99:
On 2/28/2024 12:19 AM, Harald Oehlmann wrote:
Am 28.02.2024 um 01:48 schrieb et99:
On 2/26/2024 12:58 AM, Harald Oehlmann wrote:
Hi ET99,
great analysis, thank you.
Unfortunately, I can not see new information in the ticket:
https://core.tcl-lang.org/tcl/info/f91ab723f3dfbc0d
Or do you mean your post 2024-02-23 07:34:22 ?
Take care,
Harald
Yes, that was what I added to the ticket.
I probably should have mentioned that my tests, and the code I was referencing was from 9.0b1, since I just now compared tclWinPipe.c from 8.6.13 to 9.0b1 and there is a bit of difference. It hadn't occurred to me that the code would be different with respect to cmd.exe /c. It appears that in 8.6.13 there's a test that is removed in 9.0b1:
if (TclWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
And that is what oehhar mentions in the ticket. I can say with confidence that the 9.0b1 code has the problem, and perhaps because that was removed.
I didn't hand build and trace 8.6.13, so that might be doing something different. There I was using magicsplat 8.6.13, but also a tclkit 8.6.9 and this might also explain why some of the failures I got were different than what Jacob was seeing.
Sorry for any confusion I might have caused. I just sent a clarification to the ticket.
Hi ET99,
no, there is no confusion, no problem. Only confusing code ;-).
It would be great if you could test the two proposed bug branches, if they work for you or not.
Take care,
Harald
I could do that but I would need to know how to get the new code. I only just learned how to build from sources on windows. I don't know how the code management system works. If you could copy out the entire file somewhere with a link, or post it somewhere on the wiki, I could grab it and do a build. It's win/tclWinPipe.c, correct? I do have a pretty good program for comparing files (beyond compare) so I could see what's different.
-et
Yes, no problem.
Go to:
https://core.tcl-lang.org/tcl/login
and log in as anonymous with the ASCII-Art password.
Then find the two proposed branches.
You may use the timeline and find the two red colored lines
https://core.tcl-lang.org/tcl/timeline
or you go to the ticket:
https://core.tcl-lang.org/tcl/info/f91ab723f3dfbc0d
within the 3rd comment titled:
oehhar added on 2024-02-26 14:09:08:
you find 2 blue links.
If you press on the links, the chckin page opens.
You see the proposed changes as a diff.
To download, look to the 2nd line from the top titled "Downloads".
I would click on "ZIP archive" to download the whole distribution.
Please come back to me in case of any questions.
Thank you and take care,
Harald
I tried to find it but to no avail. I only am really in a position to build 9.0b1. When the next 9.0 beta comes out I can take a look, assuming the fix will go in there. Sorry.
No, sorry. The fix will go nowhere, as nobody cares.
I tried, I failed - end of the story....
Sorry,
Harald
On 2/29/2024 2:06 AM, Harald Oehlmann wrote:
Am 29.02.2024 um 10:40 schrieb et99:
On 2/28/2024 11:41 AM, Harald Oehlmann wrote:
Am 28.02.2024 um 20:25 schrieb et99:
On 2/28/2024 12:19 AM, Harald Oehlmann wrote:
Am 28.02.2024 um 01:48 schrieb et99:
On 2/26/2024 12:58 AM, Harald Oehlmann wrote:
Hi ET99,
great analysis, thank you.
Unfortunately, I can not see new information in the ticket:
https://core.tcl-lang.org/tcl/info/f91ab723f3dfbc0d
Or do you mean your post 2024-02-23 07:34:22 ?
Take care,
Harald
Yes, that was what I added to the ticket.
I probably should have mentioned that my tests, and the code I was referencing was from 9.0b1, since I just now compared tclWinPipe.c from 8.6.13 to 9.0b1 and there is a bit of difference. It hadn't occurred to me that the code would be different with respect to cmd.exe /c. It appears that in 8.6.13 there's a test that is removed in 9.0b1:
if (TclWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
And that is what oehhar mentions in the ticket. I can say with confidence that the 9.0b1 code has the problem, and perhaps because that was removed.
I didn't hand build and trace 8.6.13, so that might be doing something different. There I was using magicsplat 8.6.13, but also a tclkit 8.6.9 and this might also explain why some of the failures I got were different than what Jacob was seeing.
Sorry for any confusion I might have caused. I just sent a clarification to the ticket.
Hi ET99,
no, there is no confusion, no problem. Only confusing code ;-).
It would be great if you could test the two proposed bug branches, if they work for you or not.
Take care,
Harald
I could do that but I would need to know how to get the new code. I only just learned how to build from sources on windows. I don't know how the code management system works. If you could copy out the entire file somewhere with a link, or post it somewhere on the wiki, I could grab it and do a build. It's win/tclWinPipe.c, correct? I do have a pretty good program for comparing files (beyond compare) so I could see what's different.
-et
Yes, no problem.
Go to:
https://core.tcl-lang.org/tcl/login
and log in as anonymous with the ASCII-Art password.
Then find the two proposed branches.
You may use the timeline and find the two red colored lines
https://core.tcl-lang.org/tcl/timeline
or you go to the ticket:
https://core.tcl-lang.org/tcl/info/f91ab723f3dfbc0d
within the 3rd comment titled:
oehhar added on 2024-02-26 14:09:08:
you find 2 blue links.
If you press on the links, the chckin page opens.
You see the proposed changes as a diff.
To download, look to the 2nd line from the top titled "Downloads".
I would click on "ZIP archive" to download the whole distribution.
Please come back to me in case of any questions.
Thank you and take care,
Harald
I tried to find it but to no avail. I only am really in a position to build 9.0b1. When the next 9.0 beta comes out I can take a look, assuming the fix will go in there. Sorry.
No, sorry. The fix will go nowhere, as nobody cares.
I tried, I failed - end of the story....
Sorry,
Harald
Found this:
Modified win/tclWinPipe.c from [accbe2dfa9] to [9bed7c6415].
Ok, downloaded a file tcl-69a34921d1.zip
The code there looks very much like the code in 9.0b1, which is less code than what was in official 8.6.13.
Built it. (took me 2 hours to figure out how without clobbering my 9.0b1 directories). Fails.
The only way to get it to work was to once again, get rid of the cmd.exe /c append, like below commented out. I don't know if that breaks anything else by never doing that line, but I'm guessing it's not needed at all.
if (HasConsole()) {
createFlags = 0;
} else if (applType == APPL_DOS) {
/*
* Under NT, 16-bit DOS applications will not run unless they can
* be attached to a console. If we are running without a console,
* run the 16-bit program as an normal process inside of a hidden
* console application, and then run that hidden console as a
* detached process.
*/
startInfo.wShowWindow = SW_HIDE;
startInfo.dwFlags |= STARTF_USESHOWWINDOW;
createFlags = CREATE_NEW_CONSOLE;
// TclDStringAppendLiteral(&cmdLine, "cmd.exe /c");
} else {
createFlags = DETACHED_PROCESS;
}
Sysop: | DaiTengu |
---|---|
Location: | Appleton, WI |
Users: | 916 |
Nodes: | 10 (1 / 9) |
Uptime: | 51:03:45 |
Calls: | 12,172 |
Calls today: | 2 |
Files: | 186,522 |
Messages: | 2,234,734 |