在Windows操作系统下。
我通过Runtime.getRuntime().exec()启动子进程;我想向进程发送一个"ctrl-c“来停止它。
我用Runtime.getRuntime().exec("ping google.com -n 100000“)做了一个小例子;代码可以在那里找到:http://pastebin.com/f6315063f
到目前为止,我尝试通过进程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信号。我该怎么做呢?
发布于 2009-12-03 05:34:34
我相信Ctrl-C被shell捕获并转换为信号(SIGINT),该信号被发送到底层进程(在本例中是您衍生的进程)。
因此,我认为您需要获取进程id,然后向该进程发送适当的信号。This question看起来非常相似,并指出了各种使用资源。
发布于 2012-04-26 23:43:50
经过大量的试验,我找到了一个我现在喜欢的解决方案。基本上,它是这样工作的: 1.获取您启动的进程的进程ID 2.将此PID传递给稍作修改的SendSignal.exe版本,该版本将发送Ctrl-C而不是Ctrl-Break
这两个步骤都不是完全直截了当的,但也差不多。对于1,您需要获取PID。Java不提供任何本机方法来获取它。有许多帖子在讨论如何做到最好。我决定在您现在需要的地方命名(参见下面代码中的getProcessIDs() )。
对于2.你需要有一个工具来发送CTRL-C到一个给定的PID。同样,Java不能做到这一点。有不同的方法可以做到这一点(例如,在python中使用包装器),但所有这些方法都有点复杂。我发现最简单的方法是使用.exe文件来完成这项工作。为此,我修改了SendSingal.exe。你可以在这里获得源码: 1.然后,简单地将所有出现"BREAK“(也是小写字母)的地方替换为"C”并重新编译。
将可执行文件重命名为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;
}
}附言:我很想在这里附加SendSignalC.exe,但我不认为我被允许这样做。无论如何,如果您有一个正在运行的cpp编译器,那么更改是简单而直接的……
发布于 2018-12-06 17:31:50
切换到Java9可以节省您的时间,Process现在有了pid属性,有关详细信息,请查看文档here。您可以很容易地杀死另一个进程,如下所示:
long pid = process.pid();
Runtime.getRuntime().exec("kill " + pid);https://stackoverflow.com/questions/1835885
复制相似问题