首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将Ctrl-C发送到Java打开的进程

将Ctrl-C发送到Java打开的进程
EN

Stack Overflow用户
提问于 2009-12-03 05:16:04
回答 4查看 28.1K关注 0票数 18

在Windows操作系统下。

我通过Runtime.getRuntime().exec()启动子进程;我想向进程发送一个"ctrl-c“来停止它。

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

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

下面是一些代码:

代码语言:javascript
复制
 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信号。我该怎么做呢?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-12-03 05:34:34

我相信Ctrl-C被shell捕获并转换为信号(SIGINT),该信号被发送到底层进程(在本例中是您衍生的进程)。

因此,我认为您需要获取进程id,然后向该进程发送适当的信号。This question看起来非常相似,并指出了各种使用资源。

票数 8
EN

Stack Overflow用户

发布于 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").

代码语言:javascript
复制
/** 
 * 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
EN

Stack Overflow用户

发布于 2018-12-06 17:31:50

切换到Java9可以节省您的时间,Process现在有了pid属性,有关详细信息,请查看文档here。您可以很容易地杀死另一个进程,如下所示:

代码语言:javascript
复制
long pid = process.pid();
Runtime.getRuntime().exec("kill " + pid);
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1835885

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档