Java 中是否有进程结束方法?



我正在尝试搜索GTA5.exe何时结束。它以"steam://rungameid"协议启动,所以我不能使用 Process#waitFor((;方法。

下面的方法检查(当前(进程是否正在运行

public static boolean isProcessRunning(String processName) throws IOException {
ProcessBuilder processBuilder = new ProcessBuilder("tasklist.exe");
Process process = processBuilder.start();
String tasksList = toString(process.getInputStream());
return tasksList.contains(processName);
}

但我想要的是类似的东西

waitUntilProcessEnds(String processname) {
}

可能是

while (isProcessRunning) {
Thread.sleep(1000);
}

而且,正如预期的那样,我的 JavaFX 应用程序冻结了。 如果我尝试在另一个线程中运行 while 方法,我的 JavaFX 应用程序会给出此错误:

java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-6
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:279)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:444)
at javafx.scene.control.Dialog.show(Dialog.java:294)
at com.thunderstorm.gta5.mod_installer.app.AppController$1$1.run(AppController.java:101)
at java.lang.Thread.run(Thread.java:748)

我也试过这个

Platform.runLater();

而这个

Platform.setImplicitExit(false);

但没有什么不同...

如何解决这个问题

此问题已编辑

有一个API,但它需要Java 9或更高版本。然后,您可以顺利完成:

String name = "GTA5.exe";
ProcessHandle.allProcesses()
.filter(ph -> ph.info().command()
.filter(s -> s.regionMatches(true,s.length()-name.length(),name,0,name.length()))
.isPresent())
.findAny()
.ifPresentOrElse(ph -> {
System.out.println("Waiting for "+ph.pid()+" "+ph.info().command().get());
ph.onExit().thenRunAsync(() -> {
// your actual action
}, Platform::runLater);
}, () -> System.out.println("No matching process found"));

ProcessHandle.onExit()返回一个CompletableFuture,该允许链接相关操作,以便在进程完成时执行。因此,您无需自己轮询该过程。

进一步注意,Platform.runLater(Runnable)Executor接口的功能签名相匹配,这允许我们使用thenRunAsync(…, Platform::runLater)来强制要求在进程退出后,应在JavaFX应用程序线程中执行相关操作(Runnable(。

我认为你的设计还可以,但你对线程有点困惑。首先,当您启动等待方法时,请继续并启动一个新线程。

new Thread( ()->{
waitUntilProcessEnds(processname);
Platform.runLater( ()-> callBackOnPlatformThread() );
}).start();

然后你需要。

public void callBackOnPlatformThread(){
System.out.println("go ahead and modify fx components.");
}

这将开始等待进程在新线程上结束,因此您的 javafx UI 将继续响应。完成后,它会在 javafx Platform 线程上回调,以便您可以修改组件。

这不会检查线程是否已启动,因此如果您有启动线程的按钮,则可以启动一堆按钮。

你想实现什么?如果你想应用程序结束时执行一些代码,那么你可以添加一个关闭钩子:

Runtime.getRuntime((.addShutdownHook((( -> { ... }(;

如果要等到外部进程结束,则可以使用:

process.waitFor((

这将阻止当前线程,直到外部进程退出。

如果您的程序一开始就没有创建该过程,则不会。

Java 不提供底层操作系统中首先未提供的操作系统级功能。 例如,在类Unix系统中,"等待进程退出"只能由相关进程的祖先执行。 在Windows中,例如,您必须拥有进程的句柄,这是您通过创建进程获得的。

你必须自己滚。创建一个线程,该线程定期检查您正在监视的进程是否存在,通过适合该进程和您的操作环境的任何方式。 在最坏的情况下,您必须分叉"ps"命令(或类似命令(并解析输出。

我不能就JavaFX问题提出建议;不是我的领域。

最新更新