Dopo un sacco di prove, ho trovato una soluzione che mi piace ora. In sostanza, funziona così: 1. Ottenere l'ID di processo del processo che è stato avviato 2. passare questo PID per una versione leggermente modificata di SendSignal.exe, che invia Ctrl-C invece di Ctrl-Break
Entrambi i passaggi non sono completamente semplici, ma quasi. Per 1. è necessario ottenere il PID. Java non fornisce alcun modo nativo per ottenerlo. Ci sono diversi thread che discutono su come fare meglio. Ho deciso per uno dove è necessario ora il nome (vedi getProcessIDs() nel codice qui sotto).
Per 2. è necessario disporre di uno strumento che invia CTRL-C a un dato PID. Ancora una volta, Java non lo fa. Esistono diversi modi per farlo (per esempio usando un involucro in pitone o così), ma tutti sono piuttosto complicato. Ho trovato il più semplice è quello di utilizzare un file .exe per fare il lavoro. Per questo, ho modificato SendSingal.exe. È possibile ottenere il codice sorgente qui: 1. Quindi, semplicemente sostituire tutte le occorrenze di "BREAK" (anche in lettere minuscole) con "C" e ricompilare.
Rinominare l'exe in SendSignalC.exe e inserirlo in una sottocartella ext \ di dove si avvia Java. Quindi esegui il codice di seguito e chiama con piacere per es. 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;
}
}
PS: Mi piacerebbe attaccare SendSignalC.exe qui, ma non credo che mi sia permesso. In ogni caso, i cambiamenti sono semplici e diretto se si dispone di un running cpp-compiler ...
In definitiva, cosa stai cercando di ottenere? –
Realizza un wrapper attorno a un vecchio DOS/windows3.L'applicazione 1/win95 – Nettogrof
dovrebbe funzionare ma dovresti inviare un'interruzione solo una volta, facendolo due volte ovviamente ucciderebbe il processo principale. –