我有一个进程(在Windows上名为chromedriver.exe
),这是在我创建Selenium Chrome Driver的新实例时创建的。
所以我不是自己开始这个过程,但是如果可能的话,我想要一个表示该过程的java.lang.Process
实例。
我想创建这样的实例的原因是我想要在Process.waitFor()
发出(如果在Windows上)Runtime.getRuntime().exec("taskkill /F /IM chromedriver.exe")
之后,要求Process
等待该进程实际终止。
我不能仅针对此特定需求引入对第三方库的新依赖。我可以使用Apache Commons中的任何内容。
所以问题是:我的代码是否有办法让WebDriver.quit()
实例代表一个未从我的代码启动的正在运行的进程?
我希望能够杀死该进程的原因是像JVM崩溃这样的突然终止可能不会让exec("taskkill...")
终止进程。因此,在创建导致进程启动的ChromeDriver实例之前,我想要杀死任何可能已存在的此类进程。
我在Windows上使用killall
来终止进程的原因(我在Linux上使用Process
)是我到目前为止找到的唯一方法,但是如果有可能的话为了获得代表该进程的Process.destroy()
实例,我还尝试使用observeOn
来查看its description“杀死子进程”中提到的“子进程”是指该进程。 / p>
答案 0 :(得分:3)
简而言之,不是Java≤8,而是可以使用Java 9 和java.lang.ProcessHandle
。
Java中的Process
并不是为任意操作系统进程建模,而是实际建模java进程的子进程,因此无法连接到另一个正在运行的进程,并希望得到Process
的所有功能:
类Process提供了从进程执行输入,执行输出到进程,等待进程完成,检查进程的退出状态以及销毁(杀死)进程的方法。
如您所见,输入和输出要求您的java进程在其他进程的stdin / stdout / stderr上拥有句柄,这只对子进程有意义。该文档还提到了“子进程”,因此暗示它是一个子进程。
在Java 9中,doc明确地以:
开头流程提供对
ProcessBuilder.start
和Runtime.exec
启动的本机流程的控制。
但是Java 9也带来了ProcessHandle
,这正是你所需要的:
ProcessHandle
标识并提供对本机进程的控制。可以监视每个单独的过程的活跃度,列出其子项,获取有关该过程的信息或将其销毁。相比之下,Process
实例由当前进程启动,并且还提供对进程输入,输出和错误流的访问。
因此,如果您可以使用Java 9运行测试,则可以尝试使用ProcessHandle.allProcesses()
查找所需的进程,然后使用.destroy()
将其终止,并使用{{3}监视其活跃度},或使用isAlive()
。
Optional<ProcessHandle> optional = ProcessHandle.allProcesses().filter(process -> {
Optional<String> command = process.info().command();
return command.isPresent() && command.get().equals("Chromedriver.exe");
}).findFirst();
if (optional.isPresent()) {
ProcessHandle processHandle = optional.get();
System.out.println("Killing process " + processHandle.pid());
processHandle.destroy();
try {
System.out.println("Waiting for process " + processHandle.pid() + " to exit...");
processHandle.onExit().get();
System.out.println("Done !");
} catch (InterruptedException|ExecutionException e) {
e.printStackTrace();
}
}
话虽如此,如果你真的想,你可以自己创建一个Process
的子类,它将提供有限的功能(即没有关于I / O,只有waitFor
和{{1 }}&amp; such)。
以下是一个可怕的示例,使用来自onExit()
的想法快速入侵Windows实施。
destroy
tasklist /FO CSV /FI "IMAGENAME eq Chromedriver.exe", to get the PID
taskkill
Linux版本使用tasklist
/FO CSV /FI "PID eq ..."
,pgrep
和kill
。
请注意,将它包装为/proc/{pid}/
的实际实例并不是很有用,因此我将关注点与实现Windows所需功能的工具类以及{{1}的子类分开了。实现为练习,以显示可能的内容,以及不可能的内容(代码中的详细信息)。因此,如果您需要,请更好地直接使用java.lang.Process
,而不是Process
。
(我在另一个过程中对此进行了测试,我不能代表ProcessTool
,您可能需要调整一些细节)
DummyProcess