I need a Java way to find a running Win process from which I know to name of the executable. I want to look whether it is running right now and I need a way to kill the process if I found it.
private static final String TASKLIST = "tasklist";
private static final String KILL = "taskkill /F /IM ";
public static boolean isProcessRunning(String serviceName) throws Exception {
Process p = Runtime.getRuntime().exec(TASKLIST);
BufferedReader reader = new BufferedReader(new InputStreamReader(
p.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
if (line.contains(serviceName)) {
return true;
}
}
return false;
}
public static void killProcess(String serviceName) throws Exception {
Runtime.getRuntime().exec(KILL + serviceName);
}
EXAMPLE:
public static void main(String args[]) throws Exception {
String processName = "WINWORD.EXE";
//System.out.print(isProcessRunning(processName));
if (isProcessRunning(processName)) {
killProcess(processName);
}
}
You can use command line windows tools tasklist and taskkill and call them from Java using Runtime.exec().
Here's a groovy way of doing it:
final Process jpsProcess = "cmd /c jps".execute()
final BufferedReader reader = new BufferedReader(new InputStreamReader(jpsProcess.getInputStream()));
def jarFileName = "FileName.jar"
def processId = null
reader.eachLine {
if (it.contains(jarFileName)) {
def args = it.split(" ")
if (processId != null) {
throw new IllegalStateException("Multiple processes found executing ${jarFileName} ids: ${processId} and ${args[0]}")
} else {
processId = args[0]
}
}
}
if (processId != null) {
def killCommand = "cmd /c TASKKILL /F /PID ${processId}"
def killProcess = killCommand.execute()
def stdout = new StringBuilder()
def stderr = new StringBuilder()
killProcess.consumeProcessOutput(stdout, stderr)
println(killCommand)
def errorOutput = stderr.toString()
if (!errorOutput.empty) {
println(errorOutput)
}
def stdOutput = stdout.toString()
if (!stdOutput.empty) {
println(stdOutput)
}
killProcess.waitFor()
} else {
System.err.println("Could not find process for jar ${jarFileName}")
}
There is a little API providing the desired functionality:
https://github.com/kohsuke/winp
Windows Process Library
You could use a command line tool for killing processes like SysInternals PsKill and SysInternals PsList.
You could also use the build-in tasklist.exe and taskkill.exe, but those are only available on Windows XP Professional and later (not in the Home Edition).
Use java.lang.Runtime.exec to execute the program.
Use the following class to kill a Windows process (if it is running). I'm using the force command line argument /F to make sure that the process specified by the /IM argument will be terminated.
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class WindowsProcess
{
private String processName;
public WindowsProcess(String processName)
{
this.processName = processName;
}
public void kill() throws Exception
{
if (isRunning())
{
getRuntime().exec("taskkill /F /IM " + processName);
}
}
private boolean isRunning() throws Exception
{
Process listTasksProcess = getRuntime().exec("tasklist");
BufferedReader tasksListReader = new BufferedReader(
new InputStreamReader(listTasksProcess.getInputStream()));
String tasksLine;
while ((tasksLine = tasksListReader.readLine()) != null)
{
if (tasksLine.contains(processName))
{
return true;
}
}
return false;
}
private Runtime getRuntime()
{
return Runtime.getRuntime();
}
}
You will have to call some native code, since IMHO there is no library that does it. Since JNI is cumbersome and hard you might try to use JNA (Java Native Access). https://jna.dev.java.net/
small change in answer written by Super kakes
private static final String KILL = "taskkill /IMF ";
Changed to ..
private static final String KILL = "taskkill /IM ";
/IMF option doesnot work .it does not kill notepad..while /IM option actually works
Related
In my program I want kill Task Manager if it's running. I've tried this:
private static final String TASKLIST = "tasklist";
private static final String KILL = "taskkill /F /IM ";
if(isProcessRunning("Taskmgr.exe")){
// TODO code application logic here
killProcess("Taskmgr.exe");
}
Here is my isProcessRunning() method:
public static boolean isProcessRunning(String servicename) throws Exception {
Process p = Runtime.getRuntime().exec(TASKLIST);
BufferedReader reader = new BufferedReader(new InputStreamReader(
p.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
if (line.contains(servicename)) {
System.err.println(line);
return true;
}
}
return false;
}
And the killprocess() method:
public static void killProcess(String serviceName) throws Exception {
Runtime.getRuntime().exec(KILL + serviceName);
}
But Task Manager is still running. What can i do?
okay as to kill taskmanager you need administrator privilage. for this download this.
now copy any one file Elevate.exe or Elevate64.exe in your java project source path.
then
Runtime.getRuntime().exec("src//Elevate64.exe TASKKILL /F /IM Taskmgr.exe");
now it will prompt for yes or no. click on yes.... and BOOM
try{
Process p = Runtime.getRuntime()
p.exec("taskkill /F /IM taskmgr.exe /T")
catch(*Enter applicable exception type here* e){
System.err.println("Caught Exception: " + e.getMessage());
}
It isn't necessary to explicitly check if the task is running. If it isn't found then the command won't be executed. Try to kill it and if you get an exception, then account for it in the catch block(s).
Have you tried to change the case of the process?
For example:
if(isProcessRunning("taskmgr.exe")){
killProcess("taskmgr.exe");
}
(Sorry for my english I'm french) I'm creating a tiny Java IDE for my school project, but I'm facing a problem with running classes under Linux (I'm using Debian 7.3), no problem with Win 8.1
I'm using ProcessBuilder class to execute the java bin with some arguments, wich are args and projectOut
args = the class we want to run
projectOut = the absolute project path+"/out"
package com.esgi.honeycode;
import java.io.*;
import java.util.Scanner;
public class CustomRun {
public static void run(String args, final String projectOut) throws IOException {
System.out.flush();
if (args != null && projectOut != null) {
//SEPARATOR is a const for the file separator
ProcessBuilder builder = new ProcessBuilder("java", "-classpath", "\"" + System.getProperty("java.class.path") + System.getProperty("path.separator") + projectOut + PropertiesShared.SEPARATOR + "out\"", args);
System.out.println(builder.command());
builder.redirectErrorStream(true);
final Process process = builder.start();
Thread outThread = new Thread()
{
#Override
public void run() {
try {
String line;
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
};
Thread inThread = new Thread() {
#Override
public void run() {
Scanner s = new Scanner(System.in);
//Need to control in before !!
while (true) {
String input = s.nextLine();
try (PrintWriter pw = new PrintWriter(new OutputStreamWriter(process.getOutputStream()))) {
pw.write(input);
pw.flush();
}
}
}
};
outThread.start();
inThread.start();
}
}
}
Testing with a simple class :
public class MyClass{
public static void main(String[] args)
{
System.out.println("TESTESTE");
}
}
the class is stored in : /home/m3te0r/HoneyCodeProjects/untitledaaa/out
And if I try to run the class, I get this output, with the command print :
[java, -classpath, "/home/m3te0r/Bureau/HoneyCode.jar:/home/m3te0r/HoneyCodeProjects/untitledaaa/out", MyClass]
Error: Could not find or load main class MyClass
Like I said, there is no problem under Win 8.1 and it also works when I run the same command in a terminal.
EDIT FOR THE ANSWER ():
Ok, so I figured out what was wrong.
I just removed the escaped double quotes fot the classpath and it worked.
I was thinking there would be a problem with spaced dir names or files, but there is not.
ProcessBuilder builder = new ProcessBuilder("java", "-classpath", System.getProperty("java.class.path") + System.getProperty("path.separator") + projectOut + PropertiesShared.SEPARATOR + "out", args);
I have been implementing a program to compile and run other applications. I was wondering if there is a way to terminate a program when my application discovers that there is an issue e.g. infinite loop. I tried to using process.Destroy() but it kills the CMD not that actual program that has infinite loop...
Your help is really appreciated.
Here is a part of my code:
synchronized (pro) {
pro.wait(30000);
}
try{
pro.exitValue();
}catch (IllegalThreadStateException ex)
{
pro.destroy();
timeLimitExceededflag = true;
System.out.println("NOT FINISHED123");
System.exit(0);
}
}
Basically I am making my application to invoke the cmd using a processBuilder. This code terminates the CMD but if it runs a program that has an infinite loop that application will be still running which affects my servers performance.
I'd suggest to use the following solution:
start your program with a title specified
get PID of the process using "tasklist" command. A CSV parser required. There are tons of available I believe, like org.apache.commons.csv.CSVParser etc :)
kill the process by "taskkill" command using PID.
Here is some part of code which may be useful:
public static final String NL = System.getProperty("line.separator", "\n");
public <T extends Appendable> int command(String... cmd) throws Exception {
return command(null, cmd);
}
public <T extends Appendable> int command(T out, String... cmd) throws Exception {
try {
final ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);
final Process proc = pb.start();
final BufferedReader rd = new BufferedReader(new InputStreamReader(proc.getInputStream()));
for (;;) {
final String line = rd.readLine();
if (line == null) {
break;
}
if (out != null) {
out.append(line);
out.append(NL);
}
}
return proc.waitFor();
} catch (InterruptedException e) {
throw new IOException(e);
}
}
public void startProcessWithTitle(String pathToExe, String title) throws Exception {
command("cmd.exe", "/C", "start", '"' + pathToExe + '"', '"' + title + '"', ..cmd.params..);
}
public int findProcessByTitle(String title) throws Exception {
final StringBuilder list = new StringBuilder();
if (command(list, "tasklist", "/V", "/FO", "csv") != 0) {
throw new RuntimeException("Cannot get tasklist. " + list.toString());
}
final CSVReader csv = new CSVReader(new StringReader(list.toString()), ',', true, "WindowsOS.findProcessByTitle");
csv.readHeaders(true); // headers
int pidIndex = csv.getHeaderIndex("PID");
int titleIndex = csv.getHeaderIndex("Window Title");
while (csv.nextLine()) {
final String ttl = csv.getString(titleIndex, true);
if (ttl.contains(title)) {
return csv.getInt(pidIndex);
}
}
Utils.close(csv);
return -1;
}
public boolean killProcess(int pid) throws Exception {
return command("taskkill", "/T", "/F", "/PID", Integer.toString(pid)) == 0;
}
Alright, i'm trying to Xbootclasspath a jar from within my project. Currently I have to load my application through command-line with the follow command:
java -Xbootclasspath/p:canvas.jar -jar application.jar
This works perfectly fine but I want to do this without having to enter command line, is there I way I can Xbootclasspath from within the jar?
Thanks.
The most clear solution is to have two main classes.
Your first class, named Boot or similar, will be the outside entry point into the application, as set in the jar's manifest. This class will form the necessary runtime command to start your actual main class (named Application or similar), with the Xboot parameter.
public class Boot {
public static void main(String[] args) {
String location = Boot.class.getProtectionDomain().getCodeSource().getLocation().getPath();
location = URLDecoder.decode(location, "UTF-8").replaceAll("\\\\", "/");
String app = Application.class.getCanonicalName();
String flags = "-Xbootclasspath/p:canvas.jar";
boolean windows = System.getProperty("os.name").contains("Win");
StringBuilder command = new StringBuilder(64);
if (windows) {
command.append("javaw");
} else {
command.append("java");
}
command.append(' ').append(flags).append(' ');
command.append('"').append(location).append('"');
// append any necessary external libraries here
for (String arg : args) {
command.append(' ').append('"').append(arg).append('"');
}
Process application = null;
Runtime runtime = Runtime.getRuntime();
if (windows) {
application = runtime.exec(command.toString());
} else {
application = runtime.exec(new String[]{ "/bin/sh", "-c", command.toString() });
}
// wire command line output to Boot to output it correctly
BufferedReader strerr = new BufferedReader(new InputStreamReader(application.getErrorStream()));
BufferedReader strin = new BufferedReader(new InputStreamReader(application.getInputStream()));
while (isRunning(application)) {
String err = null;
while ((err = strerr.readLine()) != null) {
System.err.println(err);
}
String in = null;
while ((in = strin.readLine()) != null) {
System.out.println(in);
}
try {
Thread.sleep(50);
} catch (InterruptedException ignored) {
}
}
}
private static boolean isRunning(Process process) {
try {
process.exitValue();
} catch (IllegalThreadStateException e) {
return true;
}
return false;
}
}
And your Application class runs your actual program:
public class Application {
public static void main(String[] args) {
// display user-interface, etc
}
}
Feels yucky, but could you do a Runtime.exec that calls to java with the provided options and a new parameter (along with some conditional code that looks for that) to prevent a recursive loop of spawning new processes?
I'm trying to execute terminal command in linux trough Java and i cant get any input from inputStream.
This is my code
ProcessBuilder build = new ProcessBuilder("/usr/bin/xterm", "find /home");
Process pr = null;
BufferedReader buf;
try {
build.redirectErrorStream(true);
pr = build.start();
buf = new BufferedReader(new InputStreamReader( pr.getInputStream()));
String line = buf.readLine();
pr.waitFor();
while (true) {
System.out.println(line + "sadasdas");
line = buf.readLine();
}
} catch (Exception e) {
e.printStackTrace();
}
Process is executed and immediately terminal closes, and no output is catched and printed. On the other hand if i will compose an unknown command i get all the lines with tips how to use commands. Same problem i had with windows cmd. I was trying to use getRuntime.exec(cmd) method but the end is the same.
I've also tried to created separate threads for process and reader which looks like this
public class kurdee
{
public static Thread thread;
public kurdee()
{
List cmd = new LinkedList();
cmd.add(new String("/usr/bin/xterm"));
cmd.add(new String("find"));
thisProc thispr = new thisProc(cmd);
this.thread = new Thread(thispr);
thread.start();
reader rd = new reader(thispr.proc);
Thread thread1 = new Thread(rd);
thread1.start();}
public static void main(String args[])
{
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
kurdee kurd = new kurdee();
}
});
}
}
class reader implements Runnable
{
private BufferedReader buf;
private Process proc;
public reader(Process proc)
{
this.proc=proc;
this.buf = new BufferedReader(new InputStreamReader(proc.getInputStream()));
}
public void run()
{
String line="";
System.out.println("Thread is alive");
try{
//Thread.sleep(1000);
line = buf.readLine();
}catch(Exception ex){System.out.println(ex + " before first while started");}
while(kurdee.thread.isAlive())
{
System.out.println("Thread is alive");
while(line!=null)
{
try{
//System.out.println(proc.exitValue());
System.out.println(line + " asd");
line=buf.readLine();
}catch(Exception e){System.out.println(e + " Inner while loop");}
}
}
}
}
class thisProc implements Runnable
{
private ProcessBuilder build;
public static Process proc=null;
public thisProc(List<String> args)
{
this.build = new ProcessBuilder(args);
build.redirectErrorStream(true);
try{
this.proc = build.start();
}catch(Exception ex){System.out.println(ex + " proc class");}
}
public void run()
{
try{
proc.waitFor();
}catch(Exception ex){System.out.println(ex + " proc class");}
}
}
But with any combination of invoking threads etc i make there is still nothing to read.
I'm trying to use command "find /home -xdev -samefile file" to get all hard links to file so maybe there is an easier way.
xterm is not the way to execute processes in unix, it is not a shell. a shell is something like "/bin/sh". however, "find" is a normal unix executable, so you should just execute that directly, e.g. new ProcessBuilder("find", "/home"). and yes, you should always process the streams on separate threads, as recommended by this article.
First, don't try to execute the command with xterm, that's pointless; just do it directly. Secondly, be careful when you compose your array of command strings to put one word into each string; passing, for example "find /home" as a single string among many to ProcessBuilder is going to error out.