我有一个使用<exec>
执行冗长构build操作的ant任务。 Ant由Windows命令行中的batch file启动。 如果通过closures窗口来终止ant任务,由<exec>
启动的进程将继续运行。 当ant进程本身终止时,我怎样才能终止产生的进程呢?
在Windows 7 x64上使用Ant 1.10.0和Oracle JDK 8.启动该过程的任务类似于:
<exec executable="${make.executable}" dir="${compile.dir}" failonerror="true"> <arg line="${make.parameters}" /> </exec>
运行ant的java
进程在closures命令行窗口时被正确终止。
这是一个可能的解决方案:
antPidFile
的参数启动Ant。 jps
工具来获取运行Ant脚本的java.exe
进程的PID。 antPidFile
。 wmic
工具来识别Ant产生的进程。 taskkill
工具来终止Ant产生的所有子进程(和孙子)。 <project name="ant-kill-child-processes" default="run" basedir="."> <target name="run"> <fail unless="antPidFile"/> <exec executable="jps"> <!-- Output the arguments passed to each process's main method. --> <arg value="-m"/> <redirector output="${antPidFile}"> <outputfilterchain> <linecontains> <!-- Match the arguments provided to this Ant script. --> <contains value="Launcher -DantPidFile=${antPidFile}"/> </linecontains> <tokenfilter> <!-- The output of the jps command follows the following pattern: --> <!-- lvmid [ [ classname | JARfilename | "Unknown"] [ arg* ] [ jvmarg* ] ] --> <!-- We want the "lvmid" at the beginning of the line. --> <replaceregex pattern="^(\d+).*$" replace="\1"/> </tokenfilter> </outputfilterchain> </redirector> </exec> <!-- As a test, spawn notepad. It will persist after this Ant script exits. --> <exec executable="notepad" spawn="true"/> </target> </project>
setlocal set DeadAntProcessIdFile=ant-pid.txt call ant "-DantPidFile=%DeadAntProcessIdFile%" rem The Ant script should have written its PID to DeadAntProcessIdFile. set /p DeadAntProcessId=< %DeadAntProcessIdFile% rem Kill any lingering processes created by the Ant script. for /f "skip=1 usebackq" %%h in ( `wmic process where "ParentProcessId=%DeadAntProcessId%" get ProcessId ^| findstr .` ) do taskkill /F /T /PID %%h