2014-09-07 1 views
4

Я работаю над приложением, которое должно запустить процесс и ждать его выхода. Иногда процесс падает (очень часто), но на самом деле это не проблема, так как у меня есть задачи по смягчению. Проблема в том, что Windows обнаруживает, что процесс разбился и запрашивает ввод пользователя, либо проверить решение в Интернете, либо просто закрыть программу.Как обнаружить крах внешнего процесса в Java?

The dialog

Я попытался решить эту проблему, ожидая завершения процесса в Runnable, переданном в ExecutorService и используя 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.)

Спасибо.

+0

'waitFor()' возвращает значение int, выходное значение процесса после завершения, нет? –

+0

Да, но только после завершения выполнения процесса. В этом случае он не заканчивается, потому что, как только происходят сбои, открывается диалоговое окно, поэтому процесс ждет ввода пользователя перед его завершением. 'waitFor()' будет терпеливо ждать, пока процесс не завершится. – Marcelo

+1

Можете ли вы 'destroy()' 'Процесс' в' Таймер', если он остается живым более чем на пару секунд?«Эффект зависит от реализации, но он может работать на вашей платформе. – trashgod

ответ

0

Как уже было предложено, вы должны использовать вызов SetErrorMode win32. Это не изменится для всей системы, но только для вашего процесса и его детей (это то, что вы хотите, по-видимому). Правильный вызов, кажется:

SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); 

Смотрите также документацию MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/ms680621%28v=vs.85%29.aspx

С уважением.

Смежные вопросы