2016-12-24 05:55:17 +01:00
|
|
|
package net.ME1312.SubServers.Bungee.Host;
|
2016-12-05 04:21:04 +01:00
|
|
|
|
2021-02-25 02:07:20 +01:00
|
|
|
import net.ME1312.Galaxi.Library.Platform;
|
2019-04-18 16:02:09 +02:00
|
|
|
import net.ME1312.Galaxi.Library.Util;
|
2020-11-16 21:34:59 +01:00
|
|
|
import net.ME1312.SubServers.Bungee.Library.Compatibility.JNA;
|
2019-01-09 18:37:02 +01:00
|
|
|
|
2016-12-05 04:21:04 +01:00
|
|
|
import java.io.File;
|
2021-02-25 02:07:20 +01:00
|
|
|
import java.io.IOException;
|
2016-12-05 04:21:04 +01:00
|
|
|
|
|
|
|
/**
|
2019-01-10 21:52:38 +01:00
|
|
|
* Executable Handler Class
|
2016-12-05 04:21:04 +01:00
|
|
|
*/
|
2019-01-04 22:51:58 +01:00
|
|
|
public class Executable {
|
|
|
|
private Executable() {}
|
2016-12-05 04:21:04 +01:00
|
|
|
|
|
|
|
/**
|
2019-01-04 22:51:58 +01:00
|
|
|
* Format a command to be executed
|
2016-12-05 04:21:04 +01:00
|
|
|
*
|
2019-01-04 22:51:58 +01:00
|
|
|
* @param gitbash Git Bash location (optional)
|
|
|
|
* @param exec Executable String
|
|
|
|
* @return
|
2016-12-05 04:21:04 +01:00
|
|
|
*/
|
2019-01-04 22:51:58 +01:00
|
|
|
public static String[] parse(String gitbash, String exec) {
|
2019-12-18 20:15:02 +01:00
|
|
|
if (exec.startsWith("java ")) {
|
|
|
|
exec = '\"' + System.getProperty("java.home") + File.separator + "bin" + File.separator + "java" + '\"' + exec.substring(4);
|
|
|
|
}
|
|
|
|
|
2019-01-04 22:51:58 +01:00
|
|
|
String[] cmd;
|
2019-01-05 00:32:01 +01:00
|
|
|
if (System.getProperty("os.name").toLowerCase().startsWith("windows")) {
|
2019-01-17 16:39:15 +01:00
|
|
|
if (gitbash != null && (exec.toLowerCase().startsWith("bash ") || exec.toLowerCase().startsWith("sh ")))
|
2019-01-05 05:35:20 +01:00
|
|
|
exec = '"' + gitbash + ((gitbash.endsWith(File.separator))?"":File.separator) + "bin" + File.separatorChar + "sh.exe\" -lc \"" +
|
|
|
|
exec.replace("\\", "/\\").replace("\"", "\\\"").replace("^", "^^").replace("%", "^%").replace("&", "^&").replace("<", "^<").replace(">", "^>").replace("|", "^|") + '"';
|
2019-01-04 22:51:58 +01:00
|
|
|
cmd = new String[]{"cmd.exe", "/q", "/c", '"'+exec+'"'};
|
2016-12-05 04:21:04 +01:00
|
|
|
} else {
|
2019-01-05 00:32:01 +01:00
|
|
|
cmd = new String[]{"sh", "-lc", exec};
|
2016-12-05 04:21:04 +01:00
|
|
|
}
|
2019-01-04 22:51:58 +01:00
|
|
|
return cmd;
|
2016-12-05 04:21:04 +01:00
|
|
|
}
|
2019-01-09 18:37:02 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the PID of a currently running process
|
|
|
|
*
|
|
|
|
* @param process Process
|
2019-01-09 22:41:37 +01:00
|
|
|
* @return Process ID (null if unknown)
|
2019-01-09 18:37:02 +01:00
|
|
|
*/
|
2021-02-25 02:07:20 +01:00
|
|
|
@SuppressWarnings("JavaReflectionMemberAccess")
|
2019-01-09 18:37:02 +01:00
|
|
|
public static Long pid(Process process) {
|
|
|
|
if (process.isAlive()) {
|
2021-02-25 02:07:20 +01:00
|
|
|
try { // Java 9 Standard
|
|
|
|
return (long) Process.class.getMethod("pid").invoke(process);
|
|
|
|
} catch (Throwable e) {
|
|
|
|
try { // Java 8 Not-so-standard
|
|
|
|
Object response = Util.reflect(process.getClass().getDeclaredField("pid"), process);
|
|
|
|
|
|
|
|
if (response instanceof Number) {
|
|
|
|
return ((Number) response).longValue();
|
|
|
|
} else throw e;
|
|
|
|
} catch (Throwable e2) {
|
|
|
|
if (Platform.getSystem() == Platform.WINDOWS) try {
|
2019-01-15 00:28:18 +01:00
|
|
|
long handle = Util.reflect(process.getClass().getDeclaredField("handle"), process);
|
2019-01-09 18:37:02 +01:00
|
|
|
|
2019-01-09 22:41:37 +01:00
|
|
|
ClassLoader jna = JNA.get();
|
|
|
|
Class<?> pc = jna.loadClass("com.sun.jna.Pointer"),
|
|
|
|
ntc = jna.loadClass("com.sun.jna.platform.win32.WinNT$HANDLE"),
|
2021-02-25 02:07:20 +01:00
|
|
|
k32c = jna.loadClass("com.sun.jna.platform.win32.Kernel32");
|
2019-01-09 22:41:37 +01:00
|
|
|
Object k32 = k32c.getField("INSTANCE").get(null),
|
|
|
|
nt = ntc.getConstructor().newInstance();
|
|
|
|
ntc.getMethod("setPointer", pc).invoke(nt, pc.getMethod("createConstant", long.class).invoke(null, handle));
|
|
|
|
return ((Number) k32c.getMethod("GetProcessId", ntc).invoke(k32, nt)).longValue();
|
2021-02-25 02:07:20 +01:00
|
|
|
} catch (Throwable e3) {
|
|
|
|
// No way to find pid, I suppose.
|
2019-01-09 18:37:02 +01:00
|
|
|
}
|
2021-02-25 02:07:20 +01:00
|
|
|
}
|
2019-01-09 18:37:02 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Terminate a currently running process
|
|
|
|
*
|
|
|
|
* @param process Process
|
|
|
|
*/
|
|
|
|
public static void terminate(Process process) {
|
|
|
|
if (process.isAlive()) {
|
2021-02-25 02:07:20 +01:00
|
|
|
Long pid = pid(process);
|
|
|
|
if (pid != null) try {
|
|
|
|
if (Platform.getSystem() == Platform.WINDOWS) {
|
|
|
|
Runtime.getRuntime().exec(new String[]{"taskkill.exe", "/T", "/F", "/PID", pid.toString()}).waitFor();
|
|
|
|
}
|
|
|
|
} catch (IOException | InterruptedException e) {}
|
|
|
|
|
|
|
|
if (process.isAlive()) {
|
|
|
|
process.destroyForcibly();
|
2019-01-09 18:37:02 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-12-05 04:21:04 +01:00
|
|
|
}
|