7

I have a Windows .bat file that starts a java program. For the sake of convenience I have created an Eclipse external tools configuration to start it directly from the IDE and to read its standard output from the Eclipse console.

However, when I terminate the process from Eclipse with the terminate button (the red square) in the Console view, the program is still running.

How to kill it from Eclipse (without creating a separate launch configuration that will search it and kill it programmatically)?

Dragan Bozanovic
  • 23,102
  • 5
  • 43
  • 110
  • Please edit your question and post the source code of your batch file that starts this java program ! – Hackoo Mar 05 '16 at 15:26
  • @Hackoo I am able to reproduce it with a simple batch file with content: `java -jar MyApp.jar`, where the application simply displays an empty window (`JFrame`). After I kill the proces from Eclipse console, the window is still visible. My actual application is a bit more complex, but the issue is the same. – Dragan Bozanovic Mar 06 '16 at 11:46
  • So what's the name of this process created by your application ? – Hackoo Mar 06 '16 at 14:59
  • 3
    I think the problem here is that you kill only the `.bat` process, not its children. This might help you: [Kill batch file in such a way that its children are killed too, in Windows](http://stackoverflow.com/questions/20892102/kill-batch-file-in-such-a-way-that-its-children-are-killed-too-in-windows). – Roman Mar 07 '16 at 00:29
  • @DraganBozanovic Did you tried my last example in the answer ? what you get as result ? – Hackoo Mar 07 '16 at 07:28
  • @Hackoo Thanks for the answer, but I am looking for a way without creating a separate launch configuration for stopping the process; killing the process from the Eclipse console would be the most convenient way (if possible of course). – Dragan Bozanovic Mar 07 '16 at 11:13
  • @DraganBozanovic Can you edit your question and post the process list by [this application in HTA](http://stackoverflow.com/questions/35198533/get-output-of-a-powershell-script-in-a-hta/35267951#35267951) – Hackoo Mar 07 '16 at 11:27
  • @Hackoo The output related to my test application is: `ProcessID: 7740 ProcessName: java.exe Handle: 7740 commandline: java -jar Test.jar ExecutablePath: C:\Program Files\Java\jre1.8.0_65\bin\java.exe` – Dragan Bozanovic Mar 07 '16 at 11:36
  • 1
    @DraganBozanovic If you want to kill all java.exe processes : `taskkill /F /IM java.exe /T` or `wmic process where "name like '%java%'" delete` – Hackoo Mar 07 '16 at 12:00
  • @Hackoo `wmic` really looks nice. – Dragan Bozanovic Mar 09 '16 at 13:38

3 Answers3

4

You should use this command TASKKILL

Syntax TASKKILL [/S system [/U username [/P [password]]]] { [/FI filter] [/PID processid | /IM imagename] } [/F] [/T]

Options /S system The remote system to connect to.

/U   [domain\]user    The user context under which
                      the command should execute.

/P   [password]       The password. Prompts for input if omitted.

/F                    Forcefully terminate the process(es).

/FI  filter           Display a set of tasks that match a
                      given criteria specified by the filter.

/PID process id       The PID of the process to be terminated.

/IM  image name       The image name of the process to be terminated.
                      Wildcard '*' can be used to specify all image names.

/T                     Tree kill: terminates the specified process
                       and any child processes which were started by it.

Filters Apply one of the Filters below:

         Imagename   eq, ne                  String
         PID         eq, ne, gt, lt, ge, le  Positive integer.
         Session     eq, ne, gt, lt, ge, le  Any valid session number.
         Status      eq, ne                  RUNNING | NOT RESPONDING
         CPUTime     eq, ne, gt, lt, ge, le  Time hh:mm:ss
         MemUsage    eq, ne, gt, lt, ge, le  Any valid integer.
         Username    eq, ne                  User name ([Domain\]User).
         Services    eq, ne                  String The service name
         Windowtitle eq, ne                  String
         Modules     eq, ne                  String The DLL name

Examples:

TASKKILL /S system /F /IM notepad.exe /T
TASKKILL /PID 1230 /PID 1241 /PID 1253 /T
TASKKILL /F /IM notepad.exe /IM mspaint.exe
TASKKILL /F /FI "PID ge 1000" /FI "WINDOWTITLE ne untitle*"
TASKKILL /F /FI "USERNAME eq NT AUTHORITY\SYSTEM" /IM notepad.exe
TASKKILL /S system /U domain\username /FI "USERNAME ne NT*" /IM *
TASKKILL /S system /U username /P password /FI "IMAGENAME eq note*"

This is an example named : ProcessKiller.bat :

To kill differents process like eclipse.exe and javaw.exe at once and log the result into a logfile for success or failure !

@echo off
cls & color 0A
Mode con cols=50 lines=6
Title ProcessKiller by Hackoo 2016
set process="eclipse.exe" "javaw.exe"
set Tmp=Tmp.txt
set LogFile=ProcessKillerLog.txt
If Exist %Tmp% Del %Tmp%
If Exist %LogFile% Del %LogFile%
For %%a in (%process%) Do Call :KillMyProcess %%a %Tmp%
Cmd /U /C Type %Tmp% > %LogFile%
If Exist %Tmp% Del %Tmp%
Start "" %LogFile%
Exit /b

:KillMyProcess
Cls 
echo.
ECHO     **************************************
Echo          Trying to kill "%~1"
ECHO     **************************************                       
(
Echo The Process :  "%~1"  
Taskkill /IM  "%~1" /F /T
Echo =======================
)>>%2 2>&1

If you want to kill all java.exe processes : Taskkill /F /IM java.exe /T or wmic process where "name like '%java%'" delete

Hackoo
  • 18,337
  • 3
  • 40
  • 70
  • Nice overview, thanks. Currently, I am going with a separate launch configuration that executes a `.bat` file with the content: `wmic process where "CommandLine like '%%something from the command line%%'" delete`, as you suggested in the comment. I would like to avoid creating separate launch configurations for stopping services, but it does the job anyway. – Dragan Bozanovic Mar 09 '16 at 13:57
3

The best workaround I found so far is a reusable external applications launcher:

import java.lang.ProcessBuilder.Redirect;

public class Main {

    public static void main(String[] args) throws Exception {
        Process process = new ProcessBuilder(args[0])
            .redirectOutput(Redirect.INHERIT)
            .redirectError(Redirect.INHERIT)
            .start();

        Thread thread = new Thread(() -> readInput(args[1]));
        thread.setDaemon(true);
        thread.start();

        process.waitFor();
    }

    private static void readInput(String commandLinePart) {
        try {
            while (System.in.read() != -1);
            killProcess(commandLinePart);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void killProcess(String commandLinePart) throws Exception {
        final String space = " ";
        String[] commandLine = "wmic process where \"commandLine like '%placeholder%'\" delete"
                .replaceAll("placeholder", commandLinePart).split(space);
        new ProcessBuilder(commandLine).start();
    }
}

The idea is to start this application instead of the external one and pass it the information about the target application as command line arguments.

The launcher application then starts the process, redirects the output and error streams (so that I see the target application output in the Eclipse console), waits until the target process is completed and waits for EOF from the standard input.

The last point actually does the trick: When I kill the process from the Eclipse console, the standard input reaches EOF, and the launcher application knows that it's time to stop the target process as well.

The Eclipse External Tools Configuration dialog looks now like this:

enter image description here

Location is always the same for all configurations and points to the start.bat file that simply runs the launcher application:

java -jar C:\ExternalProcessManager\ExternalProcessManager.jar %1 %2

It also takes the two command line arguments:

  1. The target process (in my case test.bat which simply starts my test application: java -jar Test.jar).
  2. The part of command line used to start the application (in my case Test.jar), so that launcher application can uniquely identify and kill the target process when I terminate the process from Eclipse console.
Dragan Bozanovic
  • 23,102
  • 5
  • 43
  • 110
0

When you run a external tool, it starts a console on Eclipse.

You just have to select and stop that console on the toolbar on the top right of the current eclipse console.

  1. Show the running consoles: Click the "display selected console" tool arrow (small computer to the right of the console toolbar).
  2. Select the external application console: Click the line with the command that runs your application (dropdown menu).
  3. Stop the application: Click the stop button (red square to the left of the console toolbar).

Eclipse console toolbar with a red circle on the "display selected console" tool and a blue circle is the "stop" tool