Process 从Tcl中启动的EXE获取输出,并暂停进一步处理,直到EXE完成

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

我正在从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"]} {
}    
# 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
ing
ever
,因为您的代码要求这样做。我们需要加点东西让等待结束。一个好方法是让等待发生在
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"