PidExecuteWatchdog.java 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package cn.exlive.monitor.utils;
  2. import com.sun.jna.Pointer;
  3. import com.sun.jna.platform.win32.WinNT;
  4. import org.apache.commons.exec.DefaultExecuteResultHandler;
  5. import org.apache.commons.exec.ExecuteWatchdog;
  6. import org.apache.commons.lang3.SystemUtils;
  7. import oshi.jna.platform.windows.Kernel32;
  8. import java.lang.reflect.Field;
  9. import java.util.Optional;
  10. /**
  11. * <pre>
  12. *
  13. * Created by zhaopx.
  14. * Date: 2025/6/30
  15. * Time: 20:00
  16. * Vendor: exlive.cn
  17. *
  18. * </pre>
  19. *
  20. * @author zhaopx
  21. */
  22. public class PidExecuteWatchdog extends ExecuteWatchdog {
  23. final DefaultExecuteResultHandler handler;
  24. /**
  25. * 执行的 cmd
  26. */
  27. Process cmdProcess = null;
  28. /**
  29. * Creates a new watchdog with a given timeout.
  30. *
  31. * @param timeoutMillis the timeout for the process in milliseconds. It must be greater than 0 or {@code INFINITE_TIMEOUT}.
  32. * @deprecated Use {@link Builder#get()}.
  33. */
  34. public PidExecuteWatchdog(long timeoutMillis, DefaultExecuteResultHandler handler) {
  35. super(timeoutMillis);
  36. this.handler = handler;
  37. }
  38. @Override
  39. public synchronized void start(final Process processToMonitor) {
  40. super.start(processToMonitor);
  41. this.cmdProcess = processToMonitor;
  42. if(handler != null && handler instanceof BrodcastExecuteResultHandler) {
  43. ((BrodcastExecuteResultHandler)handler).onProcessStart(processToMonitor);
  44. }
  45. }
  46. /**
  47. * 获取进程PID
  48. * @return
  49. */
  50. public int getProcessPid() {
  51. // 获取进程PID
  52. return this.cmdProcess == null ? -1 : getPid(this.cmdProcess).orElseGet(() -> -1);
  53. }
  54. /** <p>获取pid<p>
  55. * @param process process
  56. * @return {@link Optional<Integer>}
  57. * @since 2023/11/6
  58. * @author CC
  59. **/
  60. public static Optional<Integer> getPid(Process process) {
  61. if (SystemUtils.IS_OS_LINUX) {
  62. /* Linux platform */
  63. try {
  64. Field pidField = process.getClass().getDeclaredField("pid");
  65. pidField.setAccessible(true);
  66. return Optional.of((Integer) pidField.get(process));
  67. } catch (NoSuchFieldException | IllegalAccessException e) {
  68. return Optional.empty();
  69. }
  70. } else if (SystemUtils.IS_OS_WINDOWS) {
  71. /* Windows platform */
  72. try {
  73. Field handleField = process.getClass().getDeclaredField("handle");
  74. handleField.setAccessible(true);
  75. long handl = (Long) handleField.get(process);
  76. Kernel32 kernel = Kernel32.INSTANCE;
  77. WinNT.HANDLE hand = new WinNT.HANDLE();
  78. hand.setPointer(Pointer.createConstant(handl));
  79. int pid = kernel.GetProcessId(hand);
  80. return Optional.of(pid);
  81. } catch (NoSuchFieldException | IllegalAccessException e) {
  82. return Optional.empty();
  83. }
  84. }
  85. return Optional.empty();
  86. }
  87. }