Después de muchas pruebas, encontré una solución que me gusta ahora. Básicamente, funciona así: 1. obtener el ID de proceso del proceso que inició 2. Pasar este PID a una versión ligeramente modificada de SendSignal.exe, que envía Ctrl-C en lugar de Ctrl-Break
Ambos pasos no son completamente sencillos, pero casi. Para 1. necesita obtener el PID. Java no proporciona ninguna forma nativa para obtenerlo. Hay una serie de discusiones discutiendo sobre cómo hacer eso mejor. Decidí por una en la que necesita ahora el nombre (vea getProcessIDs() en el código a continuación).
Para 2. usted necesita tener una herramienta que envíe CTRL-C a un PID dado. Nuevamente, Java no hace esto. Existen diferentes formas de hacerlo (por ejemplo, utilizar un contenedor en python), pero todas son algo complicadas. Encontré el más fácil es usar un archivo .exe para hacer el trabajo. Para esto, modifiqué SendSingal.exe. Puede obtener el código fuente aquí: 1. Luego, simplemente reemplace todas las ocurrencias de "BREAK" (también en letras minúsculas) por "C" y vuelva a compilar.
Cambie el nombre del exe a SendSignalC.exe y colóquelo en una subcarpeta ext \ donde inicia Java. A continuación, ejecute el siguiente código y felizmente llame, p. SendCTRLC.sendCtrlC ("howeveryourprogramiscall.exe").
/**
* Sends CTRL-C to running processes from Java (in Windows)
* and ca get ProcessID(s) for a given process name.
* IMPORTANT!
* This function NEEDS SendSignalC.exe in the ext\ subdirectory.
* @author Kai Goergen
*/
import java.io.*;
import java.util.*;
public class SendCTRLC() {
/**
* Get all PIDs for a given name and send CTRL-C to all
* @param processName
* @return
*/
public static List<String> sendCTRLC(String processName) {
// get all ProcessIDs for the processName
List<String> processIDs = getProcessIDs(processName);
System.out.println("" + processIDs.size() + " PIDs found for " + processName + ": " + processIDs.toString());
for (String pid : processIDs) {
// close it
sendCTRLC(Integer.parseInt(pid));
}
return processIDs;
}
/**
* Send CTRL-C to the process using a given PID
* @param processID
*/
public static void sendCTRLC(int processID) {
System.out.println(" Sending CTRL+C to PID " + processID);
try {
Process p = Runtime.getRuntime().exec("cmd /c ext\\SendSignalC.exe " + processID);
StreamGobbler.StreamGobblerLOGProcess(p);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Get List of PIDs for a given process name
* @param processName
* @return
*/
public static List<String> getProcessIDs(String processName) {
List<String> processIDs = new ArrayList<String>();
try {
String line;
Process p = Runtime.getRuntime().exec("tasklist /v /fo csv");
BufferedReader input = new BufferedReader
(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
if (!line.trim().equals("")) {
// Pid is after the 1st ", thus it's argument 3 after splitting
String currentProcessName = line.split("\"")[1];
// Pid is after the 3rd ", thus it's argument 3 after splitting
String currentPID = line.split("\"")[3];
if (currentProcessName.equalsIgnoreCase(processName)) {
processIDs.add(currentPID);
}
}
}
input.close();
}
catch (Exception err) {
err.printStackTrace();
}
return processIDs;
}
}
PD: Me gustaría conectar SendSignalC.exe aquí, pero no creo que se me permite. De todos modos, los cambios son simples y directo si tiene un compilador de CPP-correr ...
En última instancia, ¿qué estás tratando de lograr? –
Haz un contenedor alrededor de un viejo DOS/windows3.La aplicación 1/win95 – Nettogrof
debería funcionar pero deberías enviar un corte solo una vez, hacerlo dos veces obviamente mataría el proceso principal. –