Как получить список текущих открытых окон / процессов с Java? - PullRequest
83 голосов
/ 10 сентября 2008

Кто-нибудь знает, как мне получить текущие открытые окна или процесс локальной машины, использующей Java?

Я пытаюсь сделать следующее: вывести список текущих открытых задач, окон или открытых процессов, как в Windows Taskmanager, но используя многоплатформенный подход - используя только Java, если это возможно.

Ответы [ 12 ]

92 голосов
/ 10 сентября 2008

Это еще один подход для анализа списка процессов с помощью команды " 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();
}

Если вы используете Windows, вам следует изменить строку: «Process p = Runtime.getRun ...» и т. Д. (3-я строка) на строку, которая выглядит следующим образом:

Process p = Runtime.getRuntime().exec
    (System.getenv("windir") +"\\system32\\"+"tasklist.exe");

Надеюсь, информация поможет!

23 голосов
/ 27 февраля 2012

В Windows есть альтернатива, использующая JNA :

import com.sun.jna.Native;
import com.sun.jna.platform.win32.*;
import com.sun.jna.win32.W32APIOptions;

public class ProcessList {

    public static void main(String[] args) {
        WinNT winNT = (WinNT) Native.loadLibrary(WinNT.class, W32APIOptions.UNICODE_OPTIONS);

        WinNT.HANDLE snapshot = winNT.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPPROCESS, new WinDef.DWORD(0));

        Tlhelp32.PROCESSENTRY32.ByReference processEntry = new Tlhelp32.PROCESSENTRY32.ByReference();

        while (winNT.Process32Next(snapshot, processEntry)) {
            System.out.println(processEntry.th32ProcessID + "\t" + Native.toString(processEntry.szExeFile));
        }

        winNT.CloseHandle(snapshot);
    }
}
22 голосов
/ 13 июля 2017

Наконец, с Java 9+ это возможно с 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("-");
}

Выход:

    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
9 голосов
/ 10 сентября 2008

Единственный способ, которым я могу думать об этом, - это вызвать приложение командной строки, которое сделает всю работу за вас, и затем отсканировать вывод (например, ps в Linux и список задач Window).

К сожалению, это будет означать, что вам придется написать несколько процедур синтаксического анализа для чтения данных из обоих.

Process proc = Runtime.getRuntime().exec ("tasklist.exe");
InputStream procOutput = proc.getInputStream ();
if (0 == proc.waitFor ()) {
    // TODO scan the procOutput for your data
}
7 голосов
/ 17 декабря 2010

YAJSW (еще один Java Service Wrapper) выглядит так, как будто он имеет основанные на JNA реализации своего интерфейса org.rzo.yajsw.os.TaskList для win32, linux, bsd и solaris и находится под LGPL лицензия. Я не пробовал вызывать этот код напрямую, но YAJSW работает очень хорошо, когда я использовал его в прошлом, поэтому у вас не должно быть слишком много забот.

5 голосов
/ 14 февраля 2016

Вы можете легко получить список запущенных процессов, используя jProcesses

List<ProcessInfo> processesList = JProcesses.getProcessList();

for (final ProcessInfo processInfo : processesList) {
    System.out.println("Process PID: " + processInfo.getPid());
    System.out.println("Process Name: " + processInfo.getName());
    System.out.println("Process Used Time: " + processInfo.getTime());
    System.out.println("Full command: " + processInfo.getCommand());
    System.out.println("------------------");
}
4 голосов
/ 13 января 2017

Для окон я использую следующее:

        Process process = new ProcessBuilder("tasklist.exe", "/fo", "csv", "/nh").start();
    new Thread(() -> {
        Scanner sc = new Scanner(process.getInputStream());
        if (sc.hasNextLine()) sc.nextLine();
        while (sc.hasNextLine()) {
            String line = sc.nextLine();
            String[] parts = line.split(",");
            String unq = parts[0].substring(1).replaceFirst(".$", "");
            String pid = parts[1].substring(1).replaceFirst(".$", "");
            System.out.println(unq + " " + pid);
        }
    }).start();
    process.waitFor();
    System.out.println("Done");
4 голосов
/ 10 сентября 2008

Нет не зависящего от платформы способа сделать это. В версии 1.6 Java был добавлен класс " Рабочий стол ", который позволяет переносить способы просмотра, редактирования, отправки по почте, открытия и печати URI. Возможно, когда-нибудь этот класс можно будет расширить для поддержки процессов, но я сомневаюсь в этом.

Если вам интересны только процессы Java, вы можете использовать java.lang.management api для получения информации о потоках / памяти в JVM.

3 голосов
/ 17 мая 2012

Использование кода для разбора ps aux для Linux и tasklist для Windows - ваши лучшие варианты, пока не появится что-то более общее.

Для окон вы можете ссылаться: http://www.rgagnon.com/javadetails/java-0593.html

Linux также может передавать результаты от ps aux до grep, что сделает обработку / поиск быстрой и легкой. Я уверен, что вы можете найти что-то подобное и для Windows.

2 голосов
/ 17 июля 2018

Это может быть полезно для приложений с JRE в комплекте: я просматриваю имя папки, из которой запускаю приложение: поэтому, если ваше приложение выполняется из:

 C:\Dev\build\SomeJavaApp\jre-9.0.1\bin\javaw.exe

тогда вы можете узнать, работает ли он уже в J9, по:

   public static void main(String[] args)
   {
    AtomicBoolean isRunning = new AtomicBoolean(false);
    ProcessHandle.allProcesses()
            .filter(ph -> ph.info().command().isPresent() && ph.info().command().get().contains("SomeJavaApp"))
            .forEach((process) -> {
                isRunning.set(true);
            });

    if (isRunning.get()) System.out.println("SomeJavaApp is running already");
   }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...