4

I am working on an application that needs to launch a process and wait for its output. Sometimes the process crashes (very often,) but is not really an issue since I have mitigation tasks. The problem is that Windows detects the process crashed and prompts for user input, to either check for a solution online, or just close the program.

The dialog

I tried to solve this by waiting for the process to complete in a Runnable submitted to an ExecutorService and using the Future returned to specify a timeout. Speed is not really a concern for the application, and the external process is supposed to run for just a couple of seconds.

This is the code I am using:

    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();
    }

The code above worked well, but the crash dialog still pops up and it doesn't go away without user interaction.

This question presents a similar problem but from a .Net perspective and proposes to suppress the pop up through the Windows registry, which I cannot do, given that its effect is global to all process in the machine.

  • Is there a way to prevent the dialog from being displayed at all?

or

  • Is there a way to detect the application crash and handle it directly from Java without needing user interaction?

Additional details:

  • I don't have the source of the external process.
  • The external process is a console based application (i.e. no GUI.)
  • Preferably I'm looking for a pure Java based solution (no JNI.)

Thank you.

Community
  • 1
  • 1
Marcelo
  • 2,062
  • 3
  • 22
  • 31
  • `waitFor()` returns an int, the exit value of the process after termination, no? – Hovercraft Full Of Eels Sep 07 '14 at 03:37
  • Yes, but only after the process execution finishes. In this case, it doesn't finishes, because as soon as the crashes happens, the dialog pops up, so the process waits for user input before finishing. `waitFor()` will patiently wait until the process finishes. – Marcelo Sep 07 '14 at 03:42
  • 1
    Can you `destroy()` the `Process` in a `Timer` if it remains alive more than "a couple of seconds?" The effect is implementation dependent, but it might work on your platform. – trashgod Sep 07 '14 at 04:14
  • What about using the second solution in your link, to use say JNA to call the Windows Kerna32 function SetErrorMode prior to running your process, but then remembering to turn it back to baseline in a finally block? – Hovercraft Full Of Eels Sep 07 '14 at 13:01
  • 1
    @trashgod, that is what the code I posted does. – Marcelo Sep 07 '14 at 15:43
  • @HovercraftFullOfEels, I wasn't aware of JNA. Indeed looks like a good option. I will try it. Thanks. – Marcelo Sep 07 '14 at 15:44
  • @Marcelo: I see that you're using `Future#get` with a `timeout`; I meant to suggest that you backstop this with a `java.util.Timer` set for "a couple of seconds" after `service.submit`. – trashgod Sep 07 '14 at 15:57

1 Answers1

0

As already suggested you should use SetErrorMode win32 call. It won't change for the whole system but only for your process and it's children (which is what you want apparently). The correct call seems to be :

SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);

See also the MSDN documentation : http://msdn.microsoft.com/en-us/library/windows/desktop/ms680621%28v=vs.85%29.aspx

Regards.

Eric Nicolas
  • 1,342
  • 1
  • 15
  • 24