Java로 현재 열려 있는 창/프로세스 목록을 얻는 방법은 무엇입니까?
문제
Java를 사용하여 현재 열려 있는 창이나 로컬 컴퓨터의 프로세스를 얻는 방법을 아는 사람이 있습니까?
내가하려는 것은 다음과 같습니다.Windows 작업 관리자와 같이 현재 열려 있는 작업, 열려 있는 창 또는 프로세스를 나열하지만 다중 플랫폼 접근 방식을 사용합니다. 가능한 경우 Java만 사용합니다.
해결책
이는 "명령에서 프로세스 목록을 구문 분석하는 또 다른 접근 방식입니다.추신 -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를 사용하는 경우 다음 줄을 변경해야 합니다."프로세스 p = Runtime.getRun..." 등...(세 번째 줄)은 다음과 같습니다.
Process p = Runtime.getRuntime().exec
(System.getenv("windir") +"\\system32\\"+"tasklist.exe");
정보가 도움이 되길 바랍니다!
다른 팁
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);
}
}
마지막으로 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
내가 생각할 수 있는 유일한 방법은 작업을 수행하는 명령줄 응용 프로그램을 호출한 다음 출력을 스크린스크래핑하는 것입니다(예: 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는 정말 잘 작동하니 너무 걱정하지 않으셔도 됩니다.
다음을 사용하여 실행 중인 프로세스 목록을 쉽게 검색할 수 있습니다. j프로세스
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 릴리스에서는 "데스크탑" 클래스가 추가되어 URI를 찾아보고, 편집하고, 메일로 보내고, 열고, 인쇄하는 이식 가능한 방법을 허용합니다.언젠가는 이 클래스가 프로세스를 지원하도록 확장될 수도 있지만 그럴지는 의문입니다.
Java 프로세스에만 관심이 있는 경우 다음을 사용할 수 있습니다. java.lang.management JVM에서 스레드/메모리 정보를 가져오기 위한 API입니다.
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 aux
리눅스와 tasklist
더 일반적인 것이 나올 때까지는 창문이 최선의 선택입니다.
창의 경우 다음을 참조할 수 있습니다. http://www.rgagnon.com/javadetails/java-0593.html
Linux는 다음의 결과를 파이프할 수 있습니다. ps aux
~을 통해 grep
처리/검색도 빠르고 쉽게 할 수 있습니다.Windows에서도 비슷한 것을 찾을 수 있을 것이라고 확신합니다.
이는 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 "사용자 이름 eq LHPL002\soft" /FI "MEMUSAGE gt 10000" /FI "Windowtitle ne N/A" /NH
이것은 작업을 가져오고 이름을 가져오고 목록에서 액세스할 수 있도록 목록에 추가하는 함수에 대한 코드입니다.데이터로 임시 파일을 생성하고, 파일을 읽고, .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();
}