protected boolean destroyProcessGracefully() {
    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;
  }
protected boolean destroyProcessGracefully()