代码之家  ›  专栏  ›  技术社区  ›  Nettogrof

用Java发送CTRL—C进程

  •  16
  • Nettogrof  · 技术社区  · 15 年前

    在Windows操作系统下。

    我通过runtime.getruntime().exec()启动子进程; 我想给进程发送一个“ctrl-c”来停止它。

    我用runtime.getruntime().exec(“ping google.com-n 100000”)做了一个小例子。 代码可以在那里找到: http://pastebin.com/f6315063f

    到目前为止,我尝试通过进程输出流发送字符“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信号。 我该怎么做?

    4 回复  |  直到 6 年前
        1
  •  8
  •   Community CDub    8 年前

    我相信ctrl-c被shell捕获并转换成信号( SIGINT )它被发送到底层进程(在本例中是生成的进程)。

    所以我认为您需要获取进程ID,然后向该进程发送适当的信号。 This question 似乎非常相似,并指出各种资源的使用。

        2
  •  5
  •   Kai    13 年前

    经过无数次的试验,我找到了一个我现在喜欢的解决方案。 基本上,它是这样工作的: 1。获取您启动的进程的进程ID 2.第2条。将此PID传递给略微修改过的sendsignal.exe版本,该版本发送ctrl-c而不是ctrl break

    这两个步骤并不是完全笔直向前,而是接近。 1。你需要有个性签名。Java没有提供任何本地方式来获取它。 有许多线程在讨论如何做到最好。 我决定在这里输入一个您现在需要的名称(请参见下面代码中的getProcessID())。

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

    将EXE重命名为StEnsialSalc.exe,并将其放在启动Java的子文件夹EXT中。然后运行下面的代码并愉快地调用,例如sendctrlc.sendctrlc(“howeveryourprogrammiscall.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编译器,那么这些更改是简单而直接的。

        3
  •  1
  •   user1079877    6 年前

    切换到Java 9并节省时间, Process pid 属性现在,检查文档 here 详情。您可以很容易地杀死另一个过程,如:

    long pid = process.pid();
    Runtime.getRuntime().exec("kill " + pid);
    
        4
  •  0
  •   Huy Hóm Hỉnh    9 年前

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

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

    希望这有帮助!