Java로 현재 열려있는 창 / 프로세스 목록을 얻는 방법은 무엇입니까?


94

Java를 사용하여 현재 열려있는 창이나 로컬 시스템의 프로세스를 얻는 방법을 아는 사람이 있습니까?

내가하려는 것은 Windows Taskmanager에서와 같이 현재 열려있는 작업, 창 또는 열려있는 프로세스를 나열하지만 가능한 경우 Java 만 사용하는 다중 플랫폼 접근 방식을 사용하는 것입니다.

답변:


104

이것은 " 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 ..."등 ... (세 번째 줄) 줄을 다음과 같이 변경해야합니다.

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

정보가 도움이되기를 바랍니다.


어떻게 프로세스 시작 시간과 종료 시간을 얻을
벅스

34
Windows에서 실행 tasklist.exe /fo csv /nh하여 CSV 형식으로 목록을 가져 오면 훨씬 쉽게 구문 분석 할 수 있습니다.
Emmanuel Bourg 2013 년

그러나 항아리 이름이 표시되지 않습니다. 내 실행 가능한 jar 이름은 helloDemo.jar입니다. 그러나 그것은 아무것도 보여주지 않습니다
Sumon Bappi

|를 추가하면 작동하지 않는 이유는 무엇입니까? grep 자바? 즉 ps -elf | grep java, 일을 반환하지 않지만 ps -elf예상대로 작동합니다.
Itay Moav -Malimovka

하단의 "창별"비트는 불필요한 것으로 보입니다. Windows 10에서 (.exec (Runtime/getRuntime) "tasklist"))(Clojure에서 Java-interop을 사용하여) tasklist디렉터리를 지정하지 않아도 프로세스를 올바르게 반환합니다 .
Carcigenicate

39

마지막으로 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

ProcessHandle을 사용하려면 어떤 가져 오기를 추가해야합니까?
Jordi

2
그 클래스에 java.lang더 가져 오기가 필요하지 않도록
Hugues M.

23

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);
    }
}

이것은 전체 명령 줄이 아닌 명령 이름 만 제공합니다. 전체 명령 줄을 가져올 수있는 방법이 있습니까?
Christopher Dancy 2013 년

2
을 호출하여 전체 경로를 가져올 수 있습니다 GetModuleFileName. 예를 보려면 stackoverflow.com/questions/7521693/… 을 참조하십시오 .
Emmanuel Bourg 2013 년

유일한 문제는 전체 명령 줄이 아닌 프로세스의 경로 만 제공한다는 것입니다. 프로세스의 전체 명령 줄을 가져올 수있는 방법이 있습니까 (예 : 'ant.bat -f helloWorld.ext')?
Christopher Dancy 2013 년

xyz.exe와 같은 특정 프로세스가 실행 중인지 확인하는 방법은 무엇입니까?
unknownbits

@ChristopherDancy하지 당신이 아직 완성도와 그것이 하나 여기에 언급되지 않은으로 만 대답을해야하는 경우 : Winodws Managment를 정보 명령 줄 (또는 단순히 Wmic.exe를)은 응용 프로그램을 실행의 많은 정보를 검색 할 수있는 방법을 제공합니다 - WMIC PROCESS또는 특정 프로세스에 대한 출력을 제한하려면 : WMIC PROCESS WHERE name='theName'. 필요한 경우 추가 필터를 사용하여 출력을 제한 할 수 있습니다. 명령 행은 (2 열 =) 반환 된 테이블의 명령 줄 컬럼에 포함되어 있습니다
로마 Vottner을

9

내가 생각할 수있는 유일한 방법은 작업을 수행하는 명령 줄 응용 프로그램을 호출 한 다음 출력을 스크랩하는 것입니다 (예 : Linux의 ps 및 Window의 작업 목록).

불행히도 두 가지 모두에서 데이터를 읽으려면 파싱 루틴을 작성해야합니다.

Process proc = Runtime.getRuntime().exec ("tasklist.exe");
InputStream procOutput = proc.getInputStream ();
if (0 == proc.waitFor ()) {
    // TODO scan the procOutput for your data
}

1
네, 이미 그것에 대해 생각했지만 Java로만 할 수 있습니다. 그리고 나는 top 대신 "ps -aux"를 사용하는 것이 더 나을 것이라고 생각합니다. 빠른 답변에 감사드립니다!
ramayac

Windows에서는 tasklistCSV를 출력하도록 프로그램을 구성 할 수 있습니다. :)
MauganRa

7

YAJSW (Yet Another Java Service Wrapper)는 win32, linux, bsd 및 solaris 용 org.rzo.yajsw.os.TaskList 인터페이스의 JNA 기반 구현을 포함하고 있으며 LGPL 라이선스를 따릅니다. 이 코드를 직접 호출 해본 적은 없지만 YAJSW는 예전에 사용해봤을 때 정말 잘 작동하기 때문에 걱정할 필요가 없습니다.


v12 +는 Apache / LGPL 이중 라이센스
harschware

5

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("------------------");
}

이 라이브러리는 매우 느린 것 같습니다 ... 이것에 대한 이유가 있습니까 (또는 vbs에서 일반적인 Java + wmi interop입니까?
Gobliins

2
나는 당신이 Windows 구현에 대해 이야기하고 있다고 생각합니다. 예, 일반적으로 WMI 쿼리에는 시간이 걸립니다. 항상 그렇듯이 사용 사례에 따라 다릅니다. 10ms마다 쿼리를 수행해야하는 경우 예, 너무 느립니다.
profesor_falken

그래, 나는 승리에 대해 이야기하고 있었다. 리눅스에서 나는 "ps ... <options>"의 사용을 발견했다. 그래서 나는 그것이 훨씬 더 빨라야한다고 생각한다
Gobliins

좋아, 원한다면 github 프로젝트에서 문제를 만들 수 있으며 결국 Win에서 성능을 향상시킬 수 있는지 살펴보고 확인할 것입니다. 사실 Linux에서 사용했기 때문에 구현을이기는 데 많은 관심을 기울이지 않았습니다. -S
profesor_falken

괜찮지 만 내가 찾던 것 : 프로세스 startTime에서 내가 틀리지 않은 경우 하루 동안 주어진 시간 (hh : mm : ss)을 제한했습니다. 날짜 + 시간 (yyyy-mm-dd-hh : mm : ss)도 가져올 수있는 옵션이 있습니까?
Gobliins

4

이를 수행하는 플랫폼 중립적 인 방법은 없습니다. Java 1.6 릴리스에서 " 데스크탑 "클래스가 추가되어 URI를 검색, 편집, 메일 링, 열기 및 인쇄 할 수있는 이식 가능한 방법이 있습니다. 이 수업은 언젠가 프로세스를 지원하기 위해 확장 될 수 있지만 의심 스럽습니다.

Java 프로세스에만 관심이있는 경우 java.lang.management api를 사용 하여 JVM에 대한 스레드 / 메모리 정보 를 가져올 수 있습니다 .


4

Windows의 경우 다음을 사용합니다.

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

이것은 번들 된 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");
}

3

좀 더 일반적인 것이 나올 때까지 코드를 사용하여 ps auxLinux 및 tasklistWindows 에서 구문 분석 하는 것이 최선의 선택입니다.

Windows의 경우 http://www.rgagnon.com/javadetails/java-0593.html을 참조 할 수 있습니다 .

Linux는 결과를 ps aux통해 파이프를 통해 grep빠르고 쉽게 처리 / 검색 할 수 있습니다. 나는 당신이 창문에서도 비슷한 것을 찾을 수 있다고 확신합니다.


작업 목록을 더 자세히 살펴볼 수도 있습니다. technet.microsoft.com/en-us/library/bb491010.aspx
James Oravec

2

아래 프로그램은 Java 9+ 버전과 만 호환 됩니다.

CurrentProcess 정보를 얻으려면

public class CurrentProcess {
    public static void main(String[] args) {
        ProcessHandle handle = ProcessHandle.current();
        System.out.println("Current Running Process Id: "+handle.pid());
        ProcessHandle.Info info = handle.info();
        System.out.println("ProcessHandle.Info : "+info);
    }
}

실행중인 모든 프로세스에 대해

import java.util.List;
import java.util.stream.Collectors;

public class AllProcesses {
    public static void main(String[] args) {
        ProcessHandle.allProcesses().forEach(processHandle -> {
            System.out.println(processHandle.pid()+" "+processHandle.info());
        });
    }
}

2

    String line;
    Process process = Runtime.getRuntime().exec("ps -e");
    process.getOutputStream().close();
    BufferedReader input =
            new BufferedReader(new InputStreamReader(process.getInputStream()));
    while ((line = input.readLine()) != null) {
        System.out.println(line); //<-- Parse data here.
    }
    input.close();

우리는 사용할 필요 process.getOutputStream.close()가 while 루프에 갇혀 얻을 것이다, 그렇지.


0
package com.vipul;

import java.applet.Applet;
import java.awt.Checkbox;
import java.awt.Choice;
import java.awt.Font;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class BatchExecuteService extends Applet {
    public Choice choice;

    public void init() 
    {
        setFont(new Font("Helvetica", Font.BOLD, 36));
        choice = new Choice();
    }

    public static void main(String[] args) {
        BatchExecuteService batchExecuteService = new BatchExecuteService();
        batchExecuteService.run();
    }

    List<String> processList = new ArrayList<String>();

    public void run() {
        try {
            Runtime runtime = Runtime.getRuntime();
            Process process = runtime.exec("D:\\server.bat");
            process.getOutputStream().close();
            InputStream inputStream = process.getInputStream();
            InputStreamReader inputstreamreader = new InputStreamReader(
                    inputStream);
            BufferedReader bufferedrReader = new BufferedReader(
                    inputstreamreader);
            BufferedReader bufferedrReader1 = new BufferedReader(
                    inputstreamreader);

            String strLine = "";
            String x[]=new String[100];
            int i=0;
            int t=0;
            while ((strLine = bufferedrReader.readLine()) != null) 
            {
        //      System.out.println(strLine);
                String[] a=strLine.split(",");
                x[i++]=a[0];
            }
    //      System.out.println("Length : "+i);

            for(int j=2;j<i;j++)
            {
                System.out.println(x[j]);
            }
        }
        catch (IOException ioException) 
        {
            ioException.printStackTrace();
        }

    }
}
   You can create batch file like 

TASKLIST / v / FI "STATUS eq running"/ FO "CSV"/ FI "Username eq LHPL002 \ soft"/ FI "MEMUSAGE gt 10000"/ FI "Windowtitle ne N / A"/ NH


0

이것은 작업을 가져오고 이름을 가져오고 목록에서 액세스 할 수 있도록 목록에 추가하는 함수에 대한 내 코드입니다. 데이터로 임시 파일을 생성하고, 파일을 읽고, .exe 접미사가있는 작업 이름을 가져오고, 프로그램이 System.exit (0)으로 종료 될 때 삭제할 파일을 정렬하고, 사용되는 프로세스를 숨 깁니다. 작업과 java.exe를 가져 와서 사용자가 프로그램을 모두 함께 실행하는 프로세스를 실수로 종료 할 수 없도록합니다.

private static final DefaultListModel tasks = new DefaultListModel();

public static void getTasks()
{
    new Thread()
    {
        @Override
        public void run()
        {
            try 
            {
                File batchFile = File.createTempFile("batchFile", ".bat");
                File logFile = File.createTempFile("log", ".txt");
                String logFilePath = logFile.getAbsolutePath();
                try (PrintWriter fileCreator = new PrintWriter(batchFile)) 
                {
                    String[] linesToPrint = {"@echo off", "tasklist.exe >>" + logFilePath, "exit"};
                    for(String string:linesToPrint)
                    {
                        fileCreator.println(string);
                    }
                    fileCreator.close();
                }
                int task = Runtime.getRuntime().exec(batchFile.getAbsolutePath()).waitFor();
                if(task == 0)
                {
                    FileReader fileOpener = new FileReader(logFile);
                    try (BufferedReader reader = new BufferedReader(fileOpener))
                    {
                        String line;
                        while(true)
                        {
                            line = reader.readLine();
                            if(line != null)
                            {
                                if(line.endsWith("K"))
                                {
                                    if(line.contains(".exe"))
                                    {
                                        int index = line.lastIndexOf(".exe", line.length());
                                        String taskName = line.substring(0, index + 4);
                                        if(! taskName.equals("tasklist.exe") && ! taskName.equals("cmd.exe") && ! taskName.equals("java.exe"))
                                        {
                                            tasks.addElement(taskName);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                reader.close();
                                break;
                            }
                        }
                    }
                }
                batchFile.deleteOnExit();
                logFile.deleteOnExit();
            } 
            catch (FileNotFoundException ex) 
            {
                Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
            } 
            catch (IOException | InterruptedException ex) 
            {
                Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
            }
            catch (NullPointerException ex)
            {
                // This stops errors from being thrown on an empty line
            }
        }
    }.start();
}

public static void killTask(String taskName)
{
    new Thread()
    {
        @Override
        public void run()
        {
            try 
            {
                Runtime.getRuntime().exec("taskkill.exe /IM " + taskName);
            } 
            catch (IOException ex) 
            {
                Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }.start();
}

또한 Windows 10 용 기본 제공 작업 관리자를 복제하기 위해이 코드를 전체 프로그램으로 만들었습니다. 관심이있는 사람이 있으면 데모를 보내드릴 수 있습니다.
Dylan Wedman
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.