¿Cómo obtener una lista de ventanas/procesos abiertos actualmente con Java?

StackOverflow https://stackoverflow.com/questions/54686

  •  09-06-2019
  •  | 
  •  

Pregunta

¿Alguien sabe cómo puedo obtener las ventanas abiertas actuales o el proceso de una máquina local usando Java?

Lo que estoy tratando de hacer es:enumere la tarea abierta actual, las ventanas o el proceso abierto, como en el Administrador de tareas de Windows, pero usando un enfoque multiplataforma, usando solo Java si es posible.

¿Fue útil?

Solución

Este es otro método para analizar la lista de procesos desde el 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();
}

Si estás usando Windows, entonces deberías cambiar la línea:"Proceso p = Runtime.getRun..." etc...(tercera línea), para uno que se parece a esto:

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

Espero que la información ayude!

Otros consejos

En Windows existe una alternativa usando 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);
    }
}

Finalmente, con Java 9+ es posible 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("-");
}

Producción:

    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

La única forma en que se me ocurre hacerlo es invocando una aplicación de línea de comandos que haga el trabajo por usted y luego copiando la salida (como ps de Linux y la lista de tareas de Windows).

Desafortunadamente, eso significará que tendrás que escribir algunas rutinas de análisis para leer los datos de ambos.

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) parece tener implementaciones basadas en JNA de su interfaz org.rzo.yajsw.os.TaskList para win32, linux, bsd y solaris y está bajo una licencia LGPL.No he intentado llamar a este código directamente, pero YAJSW funciona muy bien cuando lo he usado en el pasado, por lo que no deberías preocuparte demasiado.

Puede recuperar fácilmente la lista de procesos en ejecución usando jProcesos

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

No existe una forma neutral de plataforma de hacer esto.En la versión 1.6 de Java, aparece un "Escritorio"Se agregó la clase que permite formas portátiles de explorar, editar, enviar por correo, abrir e imprimir URI.Es posible que esta clase algún día se extienda a procesos de soporte, pero lo dudo.

Si sólo tiene curiosidad sobre los procesos de Java, puede utilizar el java.lang.management api para obtener información de subprocesos/memoria en la JVM.

Para Windows uso lo siguiente:

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

Usando código para analizar ps aux para Linux y tasklist para Windows son sus mejores opciones, hasta que aparezca algo más general.

Para Windows, puede hacer referencia a: http://www.rgagnon.com/javadetails/java-0593.html

Linux puede canalizar los resultados de ps aux a través de grep también, lo que haría que el procesamiento/búsqueda fuera rápido y sencillo.Estoy seguro de que también puedes encontrar algo similar para Windows.

Esto puede resultar útil para aplicaciones con un JRE incluido:Busco el nombre de la carpeta desde la que estoy ejecutando la aplicación:entonces, si su aplicación se ejecuta desde:

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

luego puedes saber si ya se está ejecutando en J9, mediante:

   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 

LISTA DE TAREAS /v /FI "ESTADO eq en ejecución" /FO "CSV" /FI "Nombre de usuario eq LHPL002\soft" /FI "MEMUSAGE gt 10000" /FI "Título de ventana ne N/A" /NH

Este es mi código para una función que obtiene las tareas y sus nombres, y también las agrega a una lista para acceder desde una lista.Crea archivos temporales con los datos, lee los archivos y obtiene el nombre de la tarea con el sufijo .exe, y organiza los archivos que se eliminarán cuando el programa haya salido con System.exit(0), también oculta los procesos que se utilizan para obtenga las tareas y también java.exe para que el usuario no pueda eliminar accidentalmente el proceso que ejecuta el programa por completo.

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();
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top