developer tip

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

optionbox 2020. 9. 21. 07:36
반응형

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


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

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


이것은 " 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");

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


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

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

내가 생각할 수있는 유일한 방법은 작업을 수행하는 명령 줄 응용 프로그램을 호출 한 다음 출력을 화면 스크래핑하는 것입니다 (예 : 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
}

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


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

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

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


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

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

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

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


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

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


This is my code for a function that gets the tasks and gets their names, also adding them into a list to be accessed from a list. It creates temp files with the data, reads the files and gets the task name with the .exe suffix, and arranges the files to be deleted when the program has exited with System.exit(0), it also hides the processes being used to get the tasks and also java.exe so that the user can't accidentally kill the process that runs the program all together.

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

참고URL : https://stackoverflow.com/questions/54686/how-to-get-a-list-of-current-open-windows-process-with-java

반응형