How can we get the main title of the application from the processId of that application.
Can we use the ProcessHandler to get the window title?
In Java 9 and later, you can use the ProcessHandle class to get information about a running process:
public class PH {
public static void main(String[] args) {
ProcessHandle.allProcesses().forEach(PH::info);
}
private static void info(final ProcessHandle processHandle) {
processHandle.info().user().ifPresent(PH::print);
processHandle.info().command().ifPresent(PH::print);
processHandle.info().commandLine().ifPresent(PH::print);
System.out.println();
}
private static void print(final String s) {
System.out.print(String.format("%s\t", s));
}
}
Approximate console output:
root /usr/libexec/secd /usr/libexec/secd
root /usr/libexec/trustd /usr/libexec/trustd --agent
user /usr/libexec/lsd /usr/libexec/lsd
I'm not sure that you will be able to get the title of an application by this way, but you can check another methods of ProcessHandle.Info class.
Also you can try to use OS-specific utils for getting information about processes:
ps -e for Linux and Mac (you can read more about it here)
tasklist.exe for Windows (you can read more about it here)
In order to call that commands you can use the next code:
String command = "ps -e";
Process process = Runtime.getRuntime().exec(command);
// Get the input stream of the command's output
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
Actually the similar question have been already asked, maybe you will find something useful here.
Example:
In order to get "window title" of all processes in OS Windows, you can run the next command:
tasklist /v /fo list |find /i "window title" |find /v "N/A"
It will print something like this:
...
Window Title: Untitled - Notepad
Window Title: Command Prompt
...
It means you can run that command using Runtime.getRuntime().exec(command) as I explained above:
String command = "tasklist /v /fo list |find /i \"window title\" |find /v \"N/A\"";
Process process = Runtime.getRuntime().exec(command);
// Get the input stream of the command's output
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
Related
I have seen similiar questions on this site, but none of them seem to address/solve my problem, so I figured there is something specifically wrong with my program. I am trying to execute a very simple command, which is to take a string of a process name from a textfield input and concatenate it to a command to return and print the title of the window. This is my code:
String line;
Process p = null;
try
{
String command = "tasklist /v /fo list /fi \"imagename eq " + tf.getText().trim() + "*\"| find /i \"window title:\"\n";
p = Runtime.getRuntime().exec(command);
BufferedReader input =
new BufferedReader(new InputStreamReader(p.getInputStream()));
System.out.println(command);
while ((line = input.readLine()) != null)
{
line = line.trim();
System.out.println(line);
}
System.out.println("done");
}
catch (IOException ioException)
{
ioException.printStackTrace();
}
However, the line returned by the InputStream is always null, even though if I put the command used in .exec() into cmd (I printed it so I know they are the exact same), it works properly, albeit after a 5 seconds or so of delay. I tried it with 2 different process names and they both worked on cmd, but not in this java program. This is the output of the above code, in case that helps (the blank line is presumably from the \n at the end of the command string):
tasklist /v /fo list /fi "imagename eq notepad*"| find /i "window title:"
done
I tried adding p.waitFor() after calling .exec(), but that didn't seem to change anything. So what am I doing wrong here?
You have two problems with launching the command. Firstly you are ignoring error stream so don't see the actual problem.
Replace p = Runtime.getRuntime().exec(command); with ProcessBuilder to get access to error message:
ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectErrorStream();
p = pb.start();
This will tell you that tasklist is not a process. Normally using full pathname would fix this type of error, but as you are using pipe the whole command must sent to to CMD.EXE to interpret pipe components correctly. Run CMD.EXE then your piped command:
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", command);
pb.redirectErrorStream();
p = pb.start();
Prints:
tasklist /v /fo list /fi "imagename eq notepad*"| find /i "window title:"
Window Title: Notepad++
done
It's also easier to read STDOUT with simple transfer:
try(var stdout = p.getInputStream()) {
stdout.transferTo(System.out); // or where-ever
}
I need to start a server using bash, so I had created an UNIX shell , but I am not able to execute it with Java from Eclipse.
I tried the following code which doesn't work :
Process proc = Runtime.getRuntime().exec(./startServer);
Here is content of the startServer file :
#!/bin/bash
cd /Users/sujitsoni/Documents/bet/client
npm start
You can try the following two options.
Option 1
Process proc = Runtime.getRuntime().exec("/bin/bash", "-c", "<Abosulte Path>/startServer");
Option 2
ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", "<Absolute Path>/startServer");
pb.directory(new File("<Absolute Path>"));
Process proc = pb.start();
A couple Of things can go wrong:
The path to the file you have given might be wrong for eclipse it can take relative path but from the command line, it will take the absolute path.
error=13, Permission denied - If the script file doesn't have required permissions. In your scenario, that might not the case as you are not getting any error.
At last, you are executing the script by java program so the output of your script will not be printed out. In your scenario, this might be the case. You need to capture the output of script from BufferedReade and print it. ( In your case server might have started but you are not seeing the logs/output of the script.
See the code sample below for printing output.
public static void main(String[] args) throws IOException, InterruptedException {
Process proc = Runtime.getRuntime().exec("./startServer");
proc.waitFor();
StringBuffer output = new StringBuffer();
BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
System.out.println(output);
}
I'm currently using ProcessBuilder to run some file like test.out.
Here is some of my code
ArrayList cmd = new ArrayList();
cmd.add("sudo");
cmd.add("./test.out");
String s = "";
try{
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.directory(new File("/myPath"));
pb.redircErrorStream(true);
Process p = pb.start();
InputStream is = p.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferReader br = new BufferReader(isr);
String line = "";
while((line = br.readLine()) !=null)
{
s+=line;
}
System.out.println(s);
}
I output the path which is correct("/myPath").
when I remove line
`cmd.add("sudo")`
the output will give me a String:
oneoflib:must be root. Did you forgot sudo?
But once I add
cmd.add("sudo");
there is nothing output.
Is there anyone whats wrong with it?
I can run sudo ./test.out from terminal which works fine.
I'm using eclipse BTW.
Thank you very much.
I guess that getting the error stream from the process could be beneficial here to help debug the problem.
This should help, consider the following bash script and let's call it yourExecutable. Let's also assume that it has all the proper permissions:
if [ "$EUID" -ne 0 ]
then echo "Please run as root"
exit
fi
echo "You are running as root"
When run without sudo it prints "Please run as root" other wise it prints "You are running as root"
The command, ie first argument in your list should be bash, if that is the shell you are using. The first argument should be -c so the commands will be read from the following string. The string should be echo <password> | sudo -S ./yourExecutable. This isn't exactly the best way to send the password to sudo, but I don't think that is the point here. The -S to sudo will prompt for the password which is written to stdout and piped over to sudo.
public static void main(String[] args) throws IOException {
Process process = new ProcessBuilder("bash", "-c", "echo <password> | sudo -S ./yourExecutable").start();
BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String string;
while((string = errorReader.readLine()) != null){
System.out.println(string);
}
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
while((string = reader.readLine()) != null){
System.out.println(string);
}
}
Output on my machine looks like:
Password:
You are running as root
I have a shell script which is sending output to console
ID=$PPID
echo the process id of the parent of this script is $ID
#fetch the parent of the program which executed this shell
read PID < <(exec ps -o ppid= "$ID")
echo the grand parent id of the script is $PID
read GPID < <(exec ps -o ppid= "$PID")
echo the grand parent id of the script is $GPID
while read -u 4 P; do
top -c -n 1 -p "$P"
done 4< <(exec pgrep -P "$PID") >&1
I am calling this script from java program and trying to display the output on console but only the output of echo is appearing. The output of top command is not appearing on the java console.
Here is my java program
import java.io.BufferedReader;
public class InformationFetcher {
public InformationFetcher() {
}
public static void main(String[] args) {
InformationFetcher informationFetcher = new InformationFetcher();
try {
Process process = Runtime.getRuntime().exec(
informationFetcher.getFilePath());
InputStream in = process.getInputStream();
printInputStream(in);
} catch (IOException e) {
e.printStackTrace();
}
}
private static void printInputStream(InputStream in) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuffer outBuffer = new StringBuffer();
String newLine = System.getProperty("line.separator");
String line;
while ((line = reader.readLine()) != null) {
outBuffer.append(line);
outBuffer.append(newLine);
}
System.out.println(outBuffer.toString());
}
public String getFilePath() {
return this.getClass().getResource("/idFetcher.sh").getPath();
}
}
output is
the process id of the parent of this script is 3721
the grand parent id of the script is 3241
the grand parent id of the script is 3240
but it should also display output of top command. Any help would be greatly appreciated.
I'm not quite sure about that how top outputs, but it seems that top doesn't send its result to STDOUT in a normal way.
However, if you want top to send its result to STDOUT in a normal way, give it the -b option:
top -b -n 1
# -b means in batch mode, which outputs to `STDOUT` normally
Below one is used for get list of processes from the windows
Process proc = Runtime.getRuntime().exec ("tasklist.exe");
But I want to get the application tab content itself
i need a solution for this
Process proc = Runtime.getRuntime().exec ( ? ? ?);
This is another aproach to parse the the process list from the command "ps -e":
try {
String line;
Process p = Runtime.getRuntime().exec("ps -e");
BufferedReader input =
new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
System.out.println(line); //<-- Parse data here.
}
input.close();
} catch (Exception err) {
err.printStackTrace();
}
If you are using Windows, then you should change the line: "Process p = Runtime.getRun..." etc... (3rd line), for one that looks like this:
Process p = Runtime.getRuntime().exec
(System.getenv("windir") +"\\system32\\"+"tasklist.exe");
Its not possible to get the application, because this are only the open windows shown on this tab. Every application is a process.
U could try this from c#:
var openWindowProcesses = System.Diagnostics.Process.GetProcesses()
.Where(p => p.MainWindowHandle != IntPtr.Zero && p.ProcessName != "explorer");
The openWindowProcesses should contains all open application which they have an active man window.
I put 'p.ProcessName != "explorer"' in the where expression because the explorer is the main process of the Desktop and it never should be closed.
To watching execution of the processes you can use "ManagementEventWatcher" class. See this please.
I am trying to give the answer, even if the post is already more than one year old.
Try with the following code snippet:
private static final String STR_MATCH = "My Java Application";
String strProcess;
BufferedReader input = null;
try {
if(System.getProperty("os.name").startsWith("Windows")) {
Process p = Runtime.getRuntime().exec(System.getenv("windir") + "\\system32\\" + "tasklist.exe /v /FI \"STATUS eq RUNNING\" /FI \"imagename eq javaw.exe\"");
input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while((strProcess = input.readLine()) != null) {
if(strProcess.contains(STR_MATCH))
/* lot of code here */
}
// Close resources
input.close();
}
catch(IOEXception ioe) {
/* handle exception */
}
The thing to notice here is the way used to get the Process p, i.e.:
Process p = Runtime.getRuntime().exec(System.getenv("windir") + "\\system32\\" + "tasklist.exe /v /FI \"STATUS eq RUNNING\" /FI \"imagename eq javaw.exe\"");
The filter /FI "STATUS eq RUNNING" /FI "imagename eq javaw.exe" that has been added when invoking tasklist.exe allows to get more information related to the process javaw.exe, including the Window/Application name.