How to Get a List of Current Open Windows/Process With Java

How to get a list of current open windows/process with Java?

Finally, with Java 9+ it is possible with ProcessHandle:

public static void main(String[] args) {
ProcessHandle.allProcesses()
.forEach(process -> System.out.println(processDetails(process)));
}

private static String processDetails(ProcessHandle process) {
return String.format("%8d %8s %10s %26s %-40s",
process.pid(),
text(process.parent().map(ProcessHandle::pid)),
text(process.info().user()),
text(process.info().startInstant()),
text(process.info().commandLine()));
}

private static String text(Optional<?> optional) {
return optional.map(Object::toString).orElse("-");
}

Output:

    1        -       root   2017-11-19T18:01:13.100Z /sbin/init
...
639 1325 www-data 2018-12-04T06:35:58.680Z /usr/sbin/apache2 -k start
...
23082 11054 huguesm 2018-12-04T10:24:22.100Z /.../java ProcessListDemo

How to get a list of running processes in Java and check if a process is running?

You need to use Microsoft's OOTB tasklist.exe utility that comes with Windows and available at C:\windows\system32\tasklist.exe. And the following line:

Process p = Runtime.getRuntime().exec("tasklist.exe");

will execute it. Then you can read this string with Scanner until it has next line. The following code gives you the list of running programs (foreground as well as background applications) running on your system:

public static void main(String[] args) throws IOException {
Process process = Runtime.getRuntime().exec("tasklist.exe");
Scanner scanner = new Scanner(new InputStreamReader(process.getInputStream()));
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
scanner.close();
}

You'll get the output like this:
Sample Image

How to get list of current running application like Task Manager except applications running in background using JAVA?

You need here the powershell cmdlet called Get-Process.

   Process process = new ProcessBuilder("powershell","\"gps| ? {$_.mainwindowtitle.length -ne 0} | Format-Table -HideTableHeaders  name, ID").start();
new Thread(() -> {
Scanner sc = new Scanner(process.getInputStream());
if (sc.hasNextLine()) sc.nextLine();
while (sc.hasNextLine()) {
String line = sc.nextLine();
System.out.println(line);
}
}).start();
process.waitFor();
System.out.println("Done");

The output would be like this:

ApplicationFrameHost 15592
chrome 12920
cmd 21104
debian 13264
Far 3968
firefox 17240
HxOutlook 4784
idea64 13644
MicrosoftEdge 8024
MicrosoftEdgeCP 13908
MicrosoftEdgeCP 14604
mstsc 24636
notepad++ 9956
OUTLOOK 9588
pycharm64 6396
rider64 10468
Teams 11540
Telegram 16760


Done

How to find and close running Win-Process which is Java app from within other Java app?

You could run

wmic process where caption="java.exe" get commandline,description,processid

to get the list of processes and their associated command line like in your screenshot. Then you get the ID of the command you want to kill and kill it with taskkill /pid xxx.

How to check if a process is running on Windows?

There is no direct way to query general processes as each OS handles them differently.

You kinda stuck with using proxies such as direct OS commands...

You can however, find a specific process using tasklist.exe with /fi parameter.

e.g: tasklist.exe /nh /fi "Imagename eq chrome.exe"

Note the mandatory double quotes.

Syntax & usage are available on MS Technet site.

Same example, filtering for "chrome.exe" in Java:

String findProcess = "chrome.exe";
String filenameFilter = "/nh /fi \"Imagename eq "+findProcess+"\"";
String tasksCmd = System.getenv("windir") +"/system32/tasklist.exe "+filenameFilter;

Process p = Runtime.getRuntime().exec(tasksCmd);
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));

ArrayList<String> procs = new ArrayList<String>();
String line = null;
while ((line = input.readLine()) != null)
procs.add(line);

input.close();

Boolean processFound = procs.stream().filter(row -> row.indexOf(findProcess) > -1).count() > 0;
// Head-up! If no processes were found - we still get:
// "INFO: No tasks are running which match the specified criteria."

Get list of processes on Windows in a charset-safe way

Can break this into 2 parts:

  1. The windows part

    From java you're executing a Windows command - externally to the jvm in "Windows land". When java Runtime class executes a windows command, it uses the DLL for consoles & so appears to windows as if the command is running in a console

    Q: When I run C:\windows\system32\tasklist.exe in a console, what is the character encoding ("code page" in windows terminology) of the result?

    • windows "chcp" command with no argument gives the active code page number for the console (e.g. 850 for Multilingual-Latin-1, 1252 for Latin-1). See Windows Microsoft Code Pages, Windows OEM Code Pages, Windows ISO Code Pages

      The default system code page is originally setup according to your system locale (type systeminfo to see this or Control Panel-> Region and Language).
    • the windows OS/.NET function getACP() also gives this info

  2. The java part:

    How do I decode a java byte stream from the windows code page of "x" (e.g. 850 or 1252)?

    • the full mapping between windows code page numbers and equivalent java charset names can be derived from here - Code Page Identifiers (Windows)
    • However, in practice one of the following prefixes can be added to achieve the mapping:

      "" (none) for ISO, "IBM" or "x-IBM" for OEM, "windows-" OR "x-windows-" for Microsoft/Windows.

      E.g. ISO-8859-1 or IBM850 or windows-1252

Full Solution:

    String cmd = System.getenv("windir") + "\\system32\\" + "chcp.com";
Process p = Runtime.getRuntime().exec(cmd);
// Use default charset here - only want digits which are "core UTF8/UTF16";
// ignore text preceding ":"
String windowsCodePage = new Scanner(
new InputStreamReader(p.getInputStream())).skip(".*:").next();

Charset charset = null;
String[] charsetPrefixes =
new String[] {"","windows-","x-windows-","IBM","x-IBM"};
for (String charsetPrefix : charsetPrefixes) {
try {
charset = Charset.forName(charsetPrefix+windowsCodePage);
break;
} catch (Throwable t) {
}
}
// If no match found, use default charset
if (charset == null) charset = Charset.defaultCharset();

cmd = System.getenv("windir") + "\\system32\\" + "tasklist.exe";
p = Runtime.getRuntime().exec(cmd);
InputStreamReader isr = new InputStreamReader(p.getInputStream(), charset);
BufferedReader input = new BufferedReader(isr);

// Debugging output
System.out.println("matched codepage "+windowsCodePage+" to charset name:"+
charset.name()+" displayName:"+charset.displayName());
String line;
while ((line = input.readLine()) != null) {
System.out.println(line);
}

Thanks for the Q! - was fun.



Related Topics



Leave a reply



Submit