发送Ctrl-C来处理由Java打开

在Windows操作系统下。

我通过Runtime.getRuntime()。exec()来启动一个subprocess。 我想发送一个“ctrl-c”到进程停止它。

我做了一个小例子,用Runtime.getRuntime()。exec(“ping google.com -n 100000”); 代码可以在这里find: http : //pastebin.com/f6315063f

到目前为止,我尝试通过Process outputStream发送字符'3'(ctrl-C字符)。

这是一些代码:

cmd = re.exec("ping google.com -n 10000"); out = new BufferedWriter (new OutputStreamWriter(cmd.getOutputStream())); input = new BufferedReader (new InputStreamReader(cmd.getInputStream())); char ctrlBreak = (char)3; //Different testing way to send the ctrlBreak; out.write(ctrlBreak); out.flush(); out.write(ctrlBreak+"\n"); out.flush(); 

我不想杀死这个进程,我只想发送一个Ctrl-C信号。 我怎样才能做到这一点?

Solutions Collecting From Web of "发送Ctrl-C来处理由Java打开"

我相信Ctrl-C被shell捕获并转换成一个信号( SIGINT ),发送到底层进程(在这种情况下是你的衍生进程)。

所以我认为你需要得到进程id,然后把适当的信号发送到这个进程。 这个问题似乎非常相似,并指出了各种使用资源。

经过大量的试验,我找到了我现在喜欢的解决方案。 基本上,它的工作原理是这样的:1.获取您启动的进程的进程ID 2.将此PID传递给SendSignal.exe的稍微修改版本,SendSignal.exe将发送Ctrl-C而不是Ctrl-Break

这两个步骤并不完全是直接的,但几乎。 对于1,你需要得到PID。 Java不提供任何本地方式来获取它。 有一些讨论如何做到最好的线程。 我决定一个你需要现在的名字(参见下面代码中的getProcessIDs())。

对于2.你需要有一个工具,发送CTRL-C到给定的PID。 再次,Java不这样做。 有不同的方法来做到这一点(例如使用python中的包装器),但它们都有些复杂。 我发现最简单的是使用.exe文件来完成这项工作。 为此,我修改了SendSingal.exe。 你可以在这里得到源代码:1.然后,简单地用“C”代替所有“BREAK”(也是小写字母)并重新编译。

将exe文件重命名为SendSignalC.exe,并将其放在启动Java的子文件夹ext \中。 然后运行下面的代码,并愉快地调用例如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:我很想在这里附加SendSignalC.exe,但我不认为我被允许。 无论如何,如果你有一个正在运行的cpp编译器,这些改变是简单而直接的。

要终止你可以用这个代码taskkill java

 Runtime.getRuntime().exec("taskkill /f /im java.exe"); 

希望这个帮助!