Nach vielen und vielen Versuchen fand ich eine Lösung, die ich jetzt mag. Grundsätzlich funktioniert es wie folgt aus: 1. die Prozess-ID des Prozesses, die Sie 2. Pass diese PID auf eine leicht modifizierte Version von SendSignal.exe gestartet, die Ctrl-C anstelle von Ctrl-Break
sendet
Beide Schritte sind nicht ganz geradlinig, aber fast. Für 1. müssen Sie die PID erhalten. Java bietet keine native Möglichkeit, es zu bekommen. Es gibt eine Reihe von Threads, die darüber diskutieren, wie man das am besten macht. Ich entschied mich für einen, wo Sie jetzt den Namen benötigen (siehe getProcessIDs() im folgenden Code).
Für 2. benötigen Sie ein Werkzeug, das STRG-C an eine bestimmte PID sendet. Auch dies tut Java nicht. Es gibt verschiedene Möglichkeiten, dies zu tun (z. B. einen Wrapper in Python oder so), aber alle sind etwas kompliziert. Ich fand das einfachste ist, eine .exe-Datei zu verwenden, um die Aufgabe zu erledigen. Dazu habe ich SendSingal.exe modifiziert. Sie können den Quellcode hier bekommen: 1. Ersetzen Sie dann einfach alle Vorkommen von "BREAK" (auch in Kleinbuchstaben) durch "C" und kompilieren Sie neu.
Benennen Sie die Exe in SendSignalC.exe um und legen Sie sie in einen Unterordner ext \ von wo Sie Java starten. Führen Sie dann den folgenden Code aus und rufen Sie z. SendCTRLC.sendCtrlC ("howeyyourourprogramiscall.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: Ich würde SendSignalC.exe lieben hier zu befestigen, aber ich glaube nicht, dass ich erlaubt bin. Wie auch immer, sind die Änderungen einfach und unkompliziert, wenn Sie einen laufenden cpp-Compiler ...
Letztlich, was versuchst du zu erreichen? –
Machen Sie einen Wrapper um ein altes DOS/Windows3.1/Win95 Anwendung – Nettogrof
sollte es funktionieren, aber Sie sollten brechen nur einmal senden, es zweimal zu tun würde offensichtlich den Hauptprozess zu töten. –