0

在我的 TCL 脚本中,我正在运行一个可以在测试完成后重新运行的进程。但是,有一个 40 秒的等待时间,以便有足够的时间让程序启动。如果程序正在运行,我不想有这 40 秒的等待期。无论如何要搜索和阅读任务列表以确定程序当前是否正在运行?我在考虑 PID,但每次运行程序时它都会发生变化,可能是因为它被放置在不同的内存区域中。

我编写了一个批处理文件来执行此过程,但随后我需要将结果传回 TCL。有什么办法可以实现吗?

4

3 回答 3

2

如果您没有 twapi,这里有一个替代方法:使用tasklist.exe

package require csv

proc getPids {imageName} {
    set noTaskMessage "INFO: No tasks are running which match the specified criteria."
    set output [exec tasklist.exe /fi "imagename eq $imageName" /fo csv /nh]
    set pidList {}
    if {$output != $noTaskMessage} {
        foreach line [split $output \n] {
            set tokens [::csv::split $line]
            lappend pidList [lindex $tokens 1]
        }
    }
    return $pidList
}

# Try it out
set imageName chrome.exe
set pids [getPids $imageName]
if {$pids == ""} {
    puts "Process $imageName is not running"
} else {
    puts "PIDs for $imageName: $pids"
}

讨论

  • “图像名称”必须包含扩展名(例如 chrome.exe)
  • /fi标志指定一个过滤器,在这种情况下,我们要按图像名称过滤
  • /fo标志指定输出格式:TABLE(默认)、LIST 和 CSV。我选择 CSV 是因为它最容易解析。
  • /nh告诉 tasklist.exe 省略标题(也就是没有标题)。
  • 如果getPids返回一个空列表,则该进程未运行。
  • getPids可能会返回多个 PID,因此您的代码必须能够处理这种情况。
于 2013-08-12T23:06:27.937 回答
1

是的,这是可能的,但您需要一个 Tcl 扩展:Twapi

要检查进程是否正在运行,您可以尝试查找具有特定名称的进程。你可以使用这个:

package require twapi
if {[llength [twapi::get_process_ids -name YOUR_EXECUTABLE.EXE]]} {
   puts "Process is currently running"
} else {
   puts "Process not running"
}

有关更多信息,请参阅有关 twapi::get_process_ids 的手册

如果您在进程启动/停止时需要通知,那会比较棘手,我必须查一下。

于 2013-08-12T21:33:50.743 回答
0

在特殊情况下,您有机会从启动的程序中读取(或者如果从其标准输入中读取,则写入程序),您可以使用 open 启动进程

set descriptor [open "|myprogram" r]

然后在管道关闭时使用“eof”检测(这意味着您必须从该通道读取数据,例如使用“读取”)

可能你可以为你的程序编写一个包装器。这个包装器可以发送到标准输出并允许调用 tcl-Script 检测程序的结束。

于 2013-08-13T06:45:59.170 回答