Come ottenere un elenco delle finestre aperte/processo con Java?
Domanda
Non so come fare ho aperto corrente di windows o di un processo di una macchina locale, utilizzando Java?
Quello che sto cercando di fare è:elenco corrente aperto compito di windows o di un processo aperto, come nel Taskmanager di Windows, ma utilizzando un approccio multipiattaforma - utilizzando solo Java se è possibile.
Soluzione
Questo è un altro approccio per analizzare il processo di lista dal comando "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();
}
Se si utilizza Windows, è necessario modificare la riga:"Il processo p = Runtime.getRun..." ecc...(Linea 3), per uno che assomiglia a questo:
Process p = Runtime.getRuntime().exec
(System.getenv("windir") +"\\system32\\"+"tasklist.exe");
La speranza, le informazioni aiuta!
Altri suggerimenti
Su Windows c'è un'alternativa all'utilizzo 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);
}
}
Infine, con Java 9+ è possibile con 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
L'unico modo che posso pensare di fare è invocare una applicazione da riga di comando che fa il lavoro per voi e poi screenscraping l'uscita (come Linux ps e Finestra tasklist).
Purtroppo, questo significa che si dovrà scrivere alcune routine di analisi per la lettura dei dati da parte di entrambi.
Process proc = Runtime.getRuntime().exec ("tasklist.exe");
InputStream procOutput = proc.getInputStream ();
if (0 == proc.waitFor ()) {
// TODO scan the procOutput for your data
}
YAJSW (Ancora un Altro Servizio Java Wrapper), sembra JNA implementazioni basate su dei suoi org.rzo.yajsw.os.TaskList interfaccia per win32, linux, bsd e solaris ed è sotto licenza LGPL.Non ho provato a chiamare questo codice direttamente, ma YAJSW funziona molto bene quando l'ho usato in passato, quindi non dovreste avere troppe preoccupazioni.
Si può facilmente recuperare l'elenco dei processi in esecuzione, utilizzando 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("------------------");
}
Non c'è una piattaforma neutrale modo di fare questo.Nella versione 1.6 di Java, un "Desktop"classe è stato aggiunto il portatile modi di navigazione, editing, mailing, di apertura, di stampa e di URI.È possibile che questa classe potrebbe un giorno essere esteso per supportare i processi, ma ho i miei dubbi.
Se siete solo curiosi nei processi Java, è possibile utilizzare il java.lang.gestione api per ottenere thread/memoria informazioni sulla JVM.
Per windows io uso il seguente:
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");
Utilizza il codice per analizzare ps aux
per linux e tasklist
per windows sono migliori opzioni, fino a qualcosa di più generale arriva.
Per windows, è possibile fare riferimento a: http://www.rgagnon.com/javadetails/java-0593.html
Linux può reindirizzare i risultati di ps aux
attraverso grep
troppo, il che renderebbe l'elaborazione/ricerca facile e veloce.Sono sicuro che si può trovare qualcosa di simile anche per windows.
Questo potrebbe essere utile per le applicazioni in bundle JRE:Ho scansione per il nome della cartella che sto eseguendo l'applicazione:quindi, se siete un'applicazione è in esecuzione da:
C:\Dev\build\SomeJavaApp\jre-9.0.1\bin\javaw.exe
poi si possono trovare se si è già in esecuzione in J9, da:
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 "STATO di eq in esecuzione" /FO "CSV" /FI "Username eq LHPL002\soft" /FI "MEMUSAGE gt 10000" /FI "Windowtitle ne N/A" /NH
Questo è il mio codice per una funzione che ottiene i compiti e ottiene i loro nomi, anche l'aggiunta di loro in una lista per l'accesso da un elenco.Crea file temporanei con i dati, legge il file e prende il nome dell'attività con l' .exe suffisso, e organizza i file per essere eliminato quando il programma è terminato con il Sistema.exit(0), si nasconde anche i processi utilizzati per ottenere i compiti e anche java.exe in modo che l'utente non può accidentalmente uccidere il processo che esegue il programma tutti insieme.
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();
}