0

I need a function whose argument is bat's fileName and a float means timeOut. I've used Process in java to do it. But if I want to stop it, I find the p.destroy() cannot stop the exe file which be called by bat file and still runs.So ,how can I stop it like "Ctrl"+"C" in cmd?

public void exec(String path, float timeOutFloat) throws IOException, InterruptedException {
    Runtime r = Runtime.getRuntime();
    Process p = r.exec(new String[] { path });
    ThreadReadExec2 thread = new ThreadReadExec2(p.getInputStream());
    thread.start();
    long timeOut = (long) ((float) timeOutFloat) * 1000;
    long time = 0;
    long onceTime = 100;
    while (thread.isAlive()) {
        Thread.sleep(onceTime);
        time += onceTime;
        if (time > timeOut) {
            p.destroy();
            Thread.sleep(onceTime);
        }
    }
    int res = p.waitFor();
    System.out.println("res:" + res);
}


class ThreadReadExec2 extends Thread {
    InputStream input;
    public ThreadReadExec2(InputStream input) {
        this.input = input;
    }

    @Override
    public void run() {
        BufferedReader ir = new BufferedReader(new InputStreamReader(input));
        try {
            String line;
            while ((line = ir.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
        }
    }
}
  • `Thread#stop()` and `Thread#destroy()` are _deprecated_ -- they are inherently unsafe and should never be used. Read the Javadoc for these methods. – Jim Garrison Jul 01 '14 at 03:26

1 Answers1

0

The reason that this is happening is likely because the destroy method is killing the command shell you invoked via the batch file, but not the process that that batch file in turn invoked.

You essentially need to kill the process tree of the batch file.

There are some methods in this question that suggest ways to accomplish this in Java, although it's somewhat roundabout (link to the one that seems the most promising):

https://stackoverflow.com/a/7627648/3583500

Community
  • 1
  • 1
khampson
  • 14,700
  • 4
  • 41
  • 43
  • Thanks. So, I cannot do it only by JAVA api? – user3778064 Jul 01 '14 at 01:40
  • Sure, no problem. The link in my answer shows a way to do it in Java, albeit in a somewhat roundabout way. In terms of the `Process` class, no -- its `destroy` method is basic and doesn't take process trees into account. Also, since it appears this has answered your question, please accept my answer (http://stackoverflow.com/tour for more info). – khampson Jul 01 '14 at 01:44
  • Thanks, I have used "tasklist" to see the status. I can get the PID of the cmd.exe(who truly runs the bat), and I can see cmd.exe and ConsoleApplication1.exe(who be called by bat) in list. The I used Runtime.getRuntime().exec("taskkill /F /T /PID " + pid); to close it. As a result , I can see only ConsoleApplication1.exe in the list. So, how can I kill the ConsoleApplication1.exe(whose name may be random)? – user3778064 Jul 01 '14 at 05:52
  • Thanks very much, I've completed it by your link.Thanks. – user3778064 Jul 01 '14 at 06:17