package cn.exlive.monitor.utils; import com.sun.jna.Pointer; import com.sun.jna.platform.win32.WinNT; import org.apache.commons.exec.DefaultExecuteResultHandler; import org.apache.commons.exec.ExecuteWatchdog; import org.apache.commons.lang3.SystemUtils; import oshi.jna.platform.windows.Kernel32; import java.lang.reflect.Field; import java.util.Optional; /** *
 *
 * Created by zhaopx.
 * Date: 2025/6/30
 * Time: 20:00
 * Vendor: exlive.cn
 *
 * 
* * @author zhaopx */ public class PidExecuteWatchdog extends ExecuteWatchdog { final DefaultExecuteResultHandler handler; /** * 执行的 cmd */ Process cmdProcess = null; /** * Creates a new watchdog with a given timeout. * * @param timeoutMillis the timeout for the process in milliseconds. It must be greater than 0 or {@code INFINITE_TIMEOUT}. * @deprecated Use {@link Builder#get()}. */ public PidExecuteWatchdog(long timeoutMillis, DefaultExecuteResultHandler handler) { super(timeoutMillis); this.handler = handler; } @Override public synchronized void start(final Process processToMonitor) { super.start(processToMonitor); this.cmdProcess = processToMonitor; if(handler != null && handler instanceof BrodcastExecuteResultHandler) { ((BrodcastExecuteResultHandler)handler).onProcessStart(processToMonitor); } } /** * 获取进程PID * @return */ public int getProcessPid() { // 获取进程PID return this.cmdProcess == null ? -1 : getPid(this.cmdProcess).orElseGet(() -> -1); } /**

获取pid

* @param process process * @return {@link Optional} * @since 2023/11/6 * @author CC **/ public static Optional getPid(Process process) { if (SystemUtils.IS_OS_LINUX) { /* Linux platform */ try { Field pidField = process.getClass().getDeclaredField("pid"); pidField.setAccessible(true); return Optional.of((Integer) pidField.get(process)); } catch (NoSuchFieldException | IllegalAccessException e) { return Optional.empty(); } } else if (SystemUtils.IS_OS_WINDOWS) { /* Windows platform */ try { Field handleField = process.getClass().getDeclaredField("handle"); handleField.setAccessible(true); long handl = (Long) handleField.get(process); Kernel32 kernel = Kernel32.INSTANCE; WinNT.HANDLE hand = new WinNT.HANDLE(); hand.setPointer(Pointer.createConstant(handl)); int pid = kernel.GetProcessId(hand); return Optional.of(pid); } catch (NoSuchFieldException | IllegalAccessException e) { return Optional.empty(); } } return Optional.empty(); } }