كيفية الحصول على قائمة بالنوافذ/العمليات المفتوحة الحالية باستخدام Java؟

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

  •  09-06-2019
  •  | 
  •  

سؤال

هل يعرف أحد كيف يمكنني الحصول على النوافذ المفتوحة الحالية أو عملية الجهاز المحلي باستخدام Java؟

ما أحاول القيام به هو:قم بإدراج المهمة المفتوحة الحالية أو النوافذ أو العملية المفتوحة، كما هو الحال في Windows Taskmanager، ولكن باستخدام نهج متعدد الأنظمة الأساسية - باستخدام Java فقط إذا كان ذلك ممكنًا.

هل كانت مفيدة؟

المحلول

هذه طريقة أخرى لتحليل قائمة العمليات من الأمر "ملاحظة -ه":

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 بديل يستخدم جينا:

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 وقائمة مهام Window).

لسوء الحظ، هذا يعني أنه سيتعين عليك كتابة بعض إجراءات التحليل لقراءة البيانات من كليهما.

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

ياجسو (يبدو أن برنامج Java Service Wrapper) يحتوي على تطبيقات مستندة إلى JNA لواجهة org.rzo.yajsw.os.TaskList الخاصة بأنظمة Win32 وlinux وbsd وsolaris، كما أنه يخضع لترخيص 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("------------------");
}

لا توجد طريقة محايدة للمنصة للقيام بذلك.في الإصدار 1.6 من Java، "سطح المكتب"تمت إضافة فئة تسمح بالطرق المحمولة للتصفح والتحرير وإرسال البريد وفتح وطباعة معرفات URI.من الممكن أن يتم توسيع هذه الفئة يومًا ما لدعم العمليات، لكنني أشك في ذلك.

إذا كنت مهتمًا فقط بعمليات Java، فيمكنك استخدام java.lang.management API للحصول على معلومات الموضوع/الذاكرة على JVM.

بالنسبة للويندوز أستخدم التالي:

        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 أيضًا، مما يجعل المعالجة/البحث سريعًا وسهلاً.أنا متأكد من أنه يمكنك العثور على شيء مماثل للنوافذ أيضًا.

قد يكون هذا مفيدًا للتطبيقات التي تحتوي على 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 

قائمة المهام /v /FI "معادل الحالة قيد التشغيل" /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();
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top