¿Cómo encontrar y matar ejecutando Win-Processes desde dentro de Java?
windows (8)
Necesito una forma Java para encontrar un proceso Win en ejecución del cual sé el nombre del ejecutable. Quiero ver si se está ejecutando ahora y necesito una forma de matar el proceso si lo encuentro.
Aquí hay una manera maravillosa de hacerlo:
final Process jpsProcess = "cmd /c jps".execute()
final BufferedReader reader = new BufferedReader(new InputStreamReader(jpsProcess.getInputStream()));
def jarFileName = "FileName.jar"
def processId = null
reader.eachLine {
if (it.contains(jarFileName)) {
def args = it.split(" ")
if (processId != null) {
throw new IllegalStateException("Multiple processes found executing ${jarFileName} ids: ${processId} and ${args[0]}")
} else {
processId = args[0]
}
}
}
if (processId != null) {
def killCommand = "cmd /c TASKKILL /F /PID ${processId}"
def killProcess = killCommand.execute()
def stdout = new StringBuilder()
def stderr = new StringBuilder()
killProcess.consumeProcessOutput(stdout, stderr)
println(killCommand)
def errorOutput = stderr.toString()
if (!errorOutput.empty) {
println(errorOutput)
}
def stdOutput = stdout.toString()
if (!stdOutput.empty) {
println(stdOutput)
}
killProcess.waitFor()
} else {
System.err.println("Could not find process for jar ${jarFileName}")
}
Hay una pequeña API que proporciona la funcionalidad deseada:
https://github.com/kohsuke/winp
Biblioteca de procesos de Windows
Puede utilizar una herramienta de línea de comandos para matar procesos como SysInternals PsKill y SysInternals PsList .
También puede usar la función incorporada tasklist.exe y taskkill.exe, pero solo están disponibles en Windows XP Professional y posterior (no en Home Edition).
Use java.lang.Runtime.exec para ejecutar el programa.
Tendrá que llamar a algún código nativo, ya que en mi humilde opinión no hay una biblioteca que lo haga. Como JNI es engorroso y difícil, puede intentar usar JNA (Java Native Access). https://jna.dev.java.net/
Utilice la siguiente clase para matar un proceso de Windows ( si se está ejecutando ). Estoy usando el argumento /F
línea de comando force para asegurarme de que el proceso especificado por el argumento /IM
finalice.
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class WindowsProcess
{
private String processName;
public WindowsProcess(String processName)
{
this.processName = processName;
}
public void kill() throws Exception
{
if (isRunning())
{
getRuntime().exec("taskkill /F /IM " + processName);
}
}
private boolean isRunning() throws Exception
{
Process listTasksProcess = getRuntime().exec("tasklist");
BufferedReader tasksListReader = new BufferedReader(
new InputStreamReader(listTasksProcess.getInputStream()));
String tasksLine;
while ((tasksLine = tasksListReader.readLine()) != null)
{
if (tasksLine.contains(processName))
{
return true;
}
}
return false;
}
private Runtime getRuntime()
{
return Runtime.getRuntime();
}
}
pequeño cambio en la respuesta escrita por Superkakes
private static final String KILL = "taskkill /IMF ";
Cambiado a ..
private static final String KILL = "taskkill /IM ";
/IMF
opción del /IMF
no funciona. No mata el bloc de notas /IM
opción de /IM
realmente funciona
Puede usar las herramientas de Windows de la línea de comandos tasklist
y taskkill
y llamarlas desde Java usando Runtime.exec()
.
private static final String TASKLIST = "tasklist";
private static final String KILL = "taskkill /F /IM ";
public static boolean isProcessRunning(String serviceName) throws Exception {
Process p = Runtime.getRuntime().exec(TASKLIST);
BufferedReader reader = new BufferedReader(new InputStreamReader(
p.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
if (line.contains(serviceName)) {
return true;
}
}
return false;
}
public static void killProcess(String serviceName) throws Exception {
Runtime.getRuntime().exec(KILL + serviceName);
}
EJEMPLO:
public static void main(String args[]) throws Exception {
String processName = "WINWORD.EXE";
//System.out.print(isProcessRunning(processName));
if (isProcessRunning(processName)) {
killProcess(processName);
}
}