Process 从Tcl中启动的EXE获取输出,并暂停进一步处理,直到EXE完成
我正在从Tcl脚本启动一个EXE,并希望从EXE获取输出,并使用简单的PUTS命令显示它,以提供用户反馈。目前,我正在CMD窗口中启动EXE,用户可以在其中看到进度,并等待EXE创建文件。这里的第一个脚本在创建输出文件LUC.CSV时工作Process 从Tcl中启动的EXE获取输出,并暂停进一步处理,直到EXE完成,process,tcl,wait,Process,Tcl,Wait,我正在从Tcl脚本启动一个EXE,并希望从EXE获取输出,并使用简单的PUTS命令显示它,以提供用户反馈。目前,我正在CMD窗口中启动EXE,用户可以在其中看到进度,并等待EXE创建文件。这里的第一个脚本在创建输出文件LUC.CSV时工作 file delete -force luc.csv set cmdStatus [open "| cmd.exe /c start /wait uc.exe"] while {![file exists "luc.csv"]} { } # cont
file delete -force luc.csv
set cmdStatus [open "| cmd.exe /c start /wait uc.exe"]
while {![file exists "luc.csv"]} {
}
# continue after output file is created
但是,有时文件没有创建,所以我不能依赖这种方法
我一直在尝试使用fileevent和pipes,并尝试了下面脚本的几个版本,但显然我要么没有抓住要点,要么就是语法不对
puts "starting"
set fifo [open "| cmd.exe /c start uc.exe" r]
fconfigure $fifo -blocking 0
proc read_fifo {fifo} {
puts "calling read_fifo"
if {[gets $fifo x] < 0} {
if {[eof $fifo]} {
close $fifo
}
}
puts "x is $x"
}
fileevent $fifo readable [list read_fifo $fifo]
vwait forever
puts"finished"
将“开始”
设置fifo[打开“| cmd.exe/c启动uc.exe”r]
fconfigure$fifo-阻止0
proc read_fifo{fifo}{
将“调用读取fifo”
如果{[gets$fifo x]<0}{
如果{[eof$fifo]}{
关闭$fifo
}
}
把“x是$x”
}
fileevent$fifo可读[列表读取\u fifo$fifo]
永远等待
把“完成”
任何帮助都将不胜感激 如果您只想启动一个子流程,在它完成之前不做任何其他事情,那么Tcl的
exec
命令非常完美
exec cmd.exe /c start /wait uc.exe
(由于您是通过start
启动GUI应用程序,除非启动时出现错误,否则不会有任何有意义的结果。在这种情况下,您将得到一个catch
able错误。)只有当您想同时做几件事情时,事情才会变得复杂
要使原始代码正常工作,您必须了解子流程已经完成。Tcl只是
vwait
ingever
,因为您的代码要求这样做。我们需要加点东西让等待结束。一个好方法是让等待发生在fifo
变量上的事情,在管道关闭后可以取消设置,因为它不再包含任何有用的内容。(vwait
一旦告诉它的变量被写入或销毁,它就有资格返回;它在封面下使用变量跟踪。在它当前正在处理的事件处理程序返回之前,它实际上也不会返回。)
将“开始”
#***假设***此代码在全局范围内
设置fifo[打开“| cmd.exe/c启动uc.exe”r]
fconfigure$fifo-阻止0
proc read_fifo{}{
全球先进先出
将“调用读取fifo”
如果{[gets$fifo x]<0}{
如果{[eof$fifo]}{
关闭$fifo
未设置fifo
}
}
把“x是$x”
}
fileevent$fifo可读读\u fifo
vwait先进先出
把“完成”
这应该行得通。更改的行是
read_fifo
的声明(没有传入变量),在下面添加global fifo
(因为我们想使用它),在close$fifo
之后添加unset fifo
,设置fileevent
(不要向回调传递额外的参数)和vwait
(因为我们要等待fifo
,而不是永远等待).谢谢您的快速回复,Donal。该代码确实可以运行脚本,但不幸的是,CMD窗口中显示的文本没有显示出来。以下是我看到的输出:开始调用read_fifo x已完成。下面是我的意思:谢谢您的快速回复,Donal。该代码确实可以运行脚本t、 但不幸的是,出现在CMD窗口中的文本(我认为通过使用[gets$fifo x]会显示为变量“x”)没有显示出来。以下是我看到的输出:开始调用read_fifo x完成了,如果我可以显示文本,我也很高兴不用CMD窗口(我想我会从puts“x是$x”中看到它)。我将尝试用exec.OK替换对CMD窗口的调用-我使用:set fifo[open”| uc.exe“r]让它以我想要的方式工作,非常感谢!
puts "starting"
# ***Assume*** that this code is in the global scope
set fifo [open "| cmd.exe /c start uc.exe" r]
fconfigure $fifo -blocking 0
proc read_fifo {} {
global fifo
puts "calling read_fifo"
if {[gets $fifo x] < 0} {
if {[eof $fifo]} {
close $fifo
unset fifo
}
}
puts "x is $x"
}
fileevent $fifo readable read_fifo
vwait fifo
puts "finished"