boolean () { ProcessService processService = getProcessService(); if (SystemInfo.isWindows) { if (processService.hasControllingTerminal(myProcess) && WinProcessTerminator.terminateWinProcessGracefully(this, processService, this::sendInterruptToPtyProcess)) { return true; } if (myMediatedProcess) { return WinRunnerMediator.destroyProcess(myProcess, true); } if (canTerminateGracefullyWithWinP() && !Registry.is("disable.winp")) { try { if (!myProcess.isAlive()) { OSProcessUtil.logSkippedActionWithTerminatedProcess(myProcess, "destroy", getCommandLine()); return true; } return WinProcessTerminator.terminateWinProcessGracefully(this, processService); } catch (Throwable e) { if (!myProcess.isAlive()) { OSProcessUtil.logSkippedActionWithTerminatedProcess(myProcess, "destroy", getCommandLine()); return true; } String message = e.getMessage(); if (message != null && message.contains(".exe terminated with exit code 6,")) { // https://github.com/kohsuke/winp/blob/ec4ac6a988f6e3909c57db0abc4b02ff1b1d2e05/native/sendctrlc/main.cpp#L18 // WinP uses AttachConsole(pid) which might fail if the specified process does not have a console. // In this case, the error code returned is ERROR_INVALID_HANDLE (6). // Let's fall back to the default termination without logging an error. String msg = "Cannot send Ctrl+C to process without a console (fallback to default termination)"; if (LOG.isDebugEnabled()) { LOG.debug(msg + " " + getCommandLine()); } else { LOG.info(msg); } } else { LOG.error("Cannot send Ctrl+C (fallback to default termination) " + getCommandLine(), e); } } } } else if (SystemInfo.isUnix) { if (processService.hasControllingTerminal(myProcess) && sendInterruptToPtyProcess()) { return true; } if (shouldDestroyProcessRecursively()) { return UnixProcessManager.sendSigIntToProcessTree(myProcess); } return UnixProcessManager.sendSignal(UnixProcessManager.getProcessId(myProcess), UnixProcessManager.SIGINT) == 0; } return false; }