2016-03-04 12 views
5

Ho un file Windows .bat che avvia un programma java. Per comodità ho creato un Eclipse external tools configuration per avviarlo direttamente dall'IDE e leggere il suo output standard dalla console di Eclipse.Come interrompere il processo avviato con una configurazione di strumenti esterni di Eclipse

Tuttavia, quando termino il processo da Eclipse con il pulsante di chiusura (il quadrato rosso) nella vista Console, il programma è ancora in esecuzione.

Come ucciderlo da Eclipse (senza creare una configurazione di avvio separata che lo cercherà e lo ucciderà a livello di codice)?

+0

Modifica la tua domanda e pubblica il codice sorgente del file batch che avvia questo programma java! – Hackoo

+0

@Hackoo Sono in grado di riprodurlo con un semplice file batch con contenuto: 'java -jar MyApp.jar', dove l'applicazione mostra semplicemente una finestra vuota (' JFrame'). Dopo aver ucciso i processi dalla console di Eclipse, la finestra è ancora visibile. La mia applicazione effettiva è un po 'più complessa, ma il problema è lo stesso. –

+0

Quindi qual è il nome di questo processo creato dalla tua applicazione? – Hackoo

risposta

2

La soluzione migliore che ho trovato finora è un riutilizzabile applicazioni esterne 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(); 
    } 
} 

L'idea è quella di iniziare questo applicazione invece di quella esterna e passare le informazioni sull'applicazione di destinazione come argomenti della riga di comando.

L'applicazione di avvio avvia quindi il processo, reindirizza i flussi di output e di errore (in modo che possa vedere l'output dell'applicazione di destinazione nella console Eclipse), attende fino al completamento del processo di destinazione e attende EOF dallo standard input.

L'ultimo punto in realtà fa il trucco: Quando ho uccidere il processo dalla console Eclipse, lo standard input raggiunge EOF, e l'avvio delle applicazioni sa che è il momento di fermare il processo di destinazione pure.

finestra strumenti di configurazione The Eclipse esterno si presenta ora così:

enter image description here

Location è sempre lo stesso per tutte le configurazioni ed i punti al file start.bat che esegue semplicemente l'applicazione launcher:

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

Prende anche i due argomenti della riga di comando:

  1. Il processo di destinazione (nel mio caso test.bat che avvia semplicemente la mia applicazione di test: java -jar Test.jar).
  2. La parte della riga di comando utilizzata per avviare l'applicazione (nel mio caso Test.jar), in modo che l'applicazione di avvio possa identificare e terminare in modo univoco il processo di destinazione quando termino il processo dalla console di Eclipse.
3

Si dovrebbe utilizzare questo comando TASKKILL

Sintassi TASKKILL [/ S sistema [/ U nomeutente [/ P [password]]]] {[filtro/FI] [/ PID processid |/IM nome immagine]} [/ F] [/ T]

Opzioni /S sistema Il sistema remoto a cui connettersi.

/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. 

Filtri Applicare uno dei filtri seguenti:

  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 

Esempi:

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*" 

Questo è un esempio di nome: ProcessKiller.bat:

Per uccidere i diversi processi come eclipse.exe e javaw.exe in una sola volta e registrare il risultato in un file di registro per il successo o l'insuccesso!

@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 

Se si vuole uccidere tutti i java.exe processi: Taskkill /F /IM java.exe /T o wmic process where "name like '%java%'" delete

+0

Bella panoramica, grazie. Attualmente, vado con una configurazione di avvio separata che esegue un file '.bat' con il contenuto:' processo wmic dove "CommandLine come '%% qualcosa dalla riga di comando %%'" delete', come suggerito nel commento . Vorrei evitare di creare configurazioni di lancio separate per l'arresto dei servizi, ma lo fa comunque. –