【发布时间】:2014-09-07 03:21:04
【问题描述】:
我正在开发一个需要启动进程并等待其输出的应用程序。有时进程会崩溃(非常频繁),但并不是真正的问题,因为我有缓解任务。问题是 Windows 检测到进程崩溃并提示用户输入,要么在线检查解决方案,要么关闭程序。
我试图通过在提交给ExecutorService 的Runnable 中等待该过程完成并使用返回的Future 来指定超时来解决此问题。速度并不是应用真正关心的问题,外部进程应该只运行几秒钟。
这是我正在使用的代码:
final Process process = ...
final ExecutorService service = Executors.newSingleThreadExecutor();
try {
final Future<?> future = service.submit(new Runnable() {
@Override
public void run() {
try {
process.waitFor();
} catch (InterruptedException e) { /* error handling */}
}
});
future.get(10, TimeUnit.SECONDS);
} catch (final TimeoutException e) {
// The process may have crashed
process.destroy();
} catch (final Exception e) {
// error handling
} finally {
service.shutdown();
}
上面的代码运行良好,但崩溃对话框仍然弹出,并且在没有用户交互的情况下不会消失。
This question 提出了类似的问题,但从 .Net 的角度来看,并且 建议通过 Windows 注册表抑制弹出窗口,我不能这样做,因为它的效果对机器中的所有进程都是全局的。
- 有没有办法完全阻止对话框显示?
或
- 有没有办法检测应用程序崩溃并直接处理 无需用户交互即可从 Java 获取?
其他细节:
- 我没有外部进程的来源。
- 外部进程是基于控制台的应用程序(即没有 GUI。)
- 最好我正在寻找基于纯 Java 的解决方案(无 JNI。)
谢谢。
【问题讨论】:
-
waitFor()返回一个int,终止后进程的退出值,不是吗? -
是的,但仅在流程执行完成后。在这种情况下,它不会完成,因为一旦发生崩溃,对话框就会弹出,因此该进程在完成之前等待用户输入。
waitFor()会耐心等待进程完成。 -
如果
Process中的Process仍然存活超过“几秒钟”,你能做到吗?效果取决于实现,但它可能适用于您的平台。 -
如何在链接中使用第二个解决方案,使用 JNA 在运行进程之前调用 Windows Kerna32 函数 SetErrorMode,然后记住在 finally 块中将其转回基线?
-
@trashgod,这就是我发布的代码的作用。
标签: java crash external-process