2008-09-10 29 views
75

Có ai biết làm thế nào để tôi có được các cửa sổ đang mở hoặc quá trình của một máy địa phương bằng cách sử dụng Java không? Những gì tôi đang cố gắng làm là: liệt kê nhiệm vụ, cửa sổ hoặc quy trình mở đang mở, như trong Windows Taskmanager, nhưng sử dụng phương pháp đa nền tảng - chỉ sử dụng Java nếu có thể.Làm cách nào để có được danh sách các cửa sổ/quy trình mở hiện tại với Java?

Trả lời

86

Đây là một cách tiếp cận để phân tích quá trình danh sách các từ lệnh "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(); 
} 

Nếu bạn đang sử dụng Windows, sau đó bạn nên thay đổi dòng: "Quy trình p = Runtime.getRun ... "v.v ... (dòng thứ ba), cho một hình như sau:

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

Hy vọng thông tin sẽ giúp!

+0

cách nhận thời gian bắt đầu quá trình và thời gian kết thúc – Bucks

+28

Trên Windows, chạy' tasklist.exe/fo csv/nh' để lấy danh sách ở định dạng CSV , phân tích cú pháp dễ dàng hơn nhiều. –

+0

nhưng không hiển thị tên bình. Tên jar thực thi của tôi là helloDemo.jar. nhưng nó không hiển thị bất cứ điều gì cho nó –

9

Cách duy nhất tôi có thể nghĩ là thực hiện bằng cách gọi một ứng dụng dòng lệnh thực hiện công việc cho bạn và sau đó sàng lọc đầu ra (như danh sách tác vụ của ps và Window của Linux).

Thật không may, điều đó có nghĩa là bạn sẽ phải viết một số thủ tục phân tích cú pháp để đọc dữ liệu từ cả hai.

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

Vâng, tôi cũng đã nghĩ về điều đó, nhưng tôi khó có thể thực hiện được chỉ với Java. Và tôi nghĩ tôi nên sử dụng "ps -aux" thay vì hàng đầu. Cảm ơn vì sớm phản hồi! – ramayac

+0

Trên Windows, chương trình 'tasklist' có thể được cấu hình để xuất CSV :) – MauganRa

4

Không có cách làm nền tảng trung lập nào để thực hiện việc này. Trong bản phát hành 1.6 của Java, một lớp "Desktop" đã được thêm vào cho phép các cách di động duyệt, chỉnh sửa, gửi thư, mở và in URI. Có thể lớp học này một ngày nào đó có thể được mở rộng để hỗ trợ các quy trình, nhưng tôi nghi ngờ nó.

Nếu bạn chỉ tò mò về các quy trình Java, bạn có thể sử dụng api java.lang.management để nhận thông tin về bộ nhớ/luồng trên JVM.

7

YAJSW (Tuy nhiên, một trình bao bọc dịch vụ Java khác) có vẻ như nó có triển khai dựa trên JNA của giao diện org.rzo.yajsw.os.TaskList của nó cho win32, linux, bsd và solaris và nằm trong giấy phép LGPL. Tôi đã không cố gắng gọi mã này trực tiếp, nhưng YAJSW hoạt động thực sự tốt khi tôi đã sử dụng nó trong quá khứ, vì vậy bạn không nên có quá nhiều lo lắng.

+0

dường như là v12 + là giấy phép kép Apache/LGPL – harschware

23

Trên Windows có một sự thay thế sử dụng 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); 
    } 
} 
+0

Lệnh này chỉ cung cấp tên lệnh KHÔNG phải là toàn bộ dòng lệnh. Có cách nào để có được toàn bộ dòng lệnh không? –

+2

Bạn có thể lấy đường dẫn đầy đủ bằng cách gọi 'GetModuleFileName'. Xem http://stackoverflow.com/questions/7521693/converting-c-sharp-to-java-jna-getmodulefilename-from-hwnd để biết ví dụ. –

+0

Vấn đề duy nhất w/điều này là nó chỉ cho phép đường dẫn của quá trình KHÔNG phải toàn bộ dòng lệnh. Có cách nào để có được dòng lệnh đầy đủ của quá trình (tức là 'ant.bat -f helloWorld.ext')? –

3

Sử dụng mã để phân tích ps aux cho Linux và tasklist cho các cửa sổ là lựa chọn tốt nhất của bạn, cho đến khi một cái gì đó tổng quát hơn đến cùng.

Đối với các cửa sổ, bạn có thể tham khảo: http://www.rgagnon.com/javadetails/java-0593.html

Linux có thể đường ống kết quả của ps aux qua grep quá, mà sẽ làm cho chế biến/tìm kiếm nhanh chóng và dễ dàng. Tôi chắc rằng bạn có thể tìm thấy một cái gì đó tương tự cho các cửa sổ quá.

+0

Bạn cũng có thể xem danh sách nhiệm vụ chi tiết hơn: http: //technet.microsoft.com/en-us/library/bb491010.aspx –

0
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 chạy"/FO "CSV"/FI "Tên đăng nhập eq LHPL002 \ mềm"/FI "gt 10000 MEMUSAGE"/FI "Windowtitle ne N/A"/ NH

5

Bạn có thể dễ dàng lấy lại danh sách các tiến trình đang chạy bằng 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("------------------"); 
} 
+0

thư viện này có vẻ rất chậm ... có lý do nào cho điều này (hoặc là nó nói chung java + wmi interop qua vbs? – Gobliins

+2

Tôi đoán bạn Có, thông thường các truy vấn WMI mất một chút thời gian, như mọi khi, nó phụ thuộc vào trường hợp sử dụng.Nếu bạn cần thực hiện truy vấn mỗi 10 ms, có, nó quá chậm –

+0

vâng tôi đã nói về chiến thắng, linux tôi phát hiện việc sử dụng "ps ... " vì vậy tôi đoán nó sẽ nhanh hơn nhiều – Gobliins

3

Đối với cửa sổ tôi sử dụng sau đây:

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

Cuối cùng, với Java 9 nó có thể với 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("-"); 
} 

Chỉnh sửa: "sẽ là" → "là"

-1

Câu hỏi tương tự (Windows running application list using Java)

Tôi đã tìm thấy câu trả lời này (https://stackoverflow.com/a/2206526) wmic.exe với đầu ra bình thường by Philippe

try{ 
     Process proc = Runtime.getRuntime().exec("wmic.exe"); 
     BufferedReader input = new BufferedReader(new InputStreamReader(proc.getInputStream())); 
     OutputStreamWriter oStream = new OutputStreamWriter(proc.getOutputStream()); 
     oStream.write("process get caption"); 
     oStream.flush(); 
     oStream.close(); 
     String line; 
     while ((line = input.readLine()) != null){ 
      if(!line.isEmpty() && !line.startsWith("wmic:root\\cli")) { 
       System.out.println(line); 
      } 
     } 
     input.close(); 
}catch (IOException ioe){ioe.printStackTrace();} 
+0

Trong khi liên kết này có thể trả lời câu hỏi, tốt hơn nên bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo. Câu trả lời chỉ liên kết có thể trở thành không hợp lệ nếu trang được liên kết thay đổi. - [Từ đánh giá] (/ đánh giá/chất lượng thấp-bài viết/17844782) – jrtapsell

+0

Tôi đến muộn, nhưng bây giờ đã bao gồm! – ecerer

Các vấn đề liên quan