我想做的是:像Windows Taskmanager一样列出当前打开的任务,窗口或打开的进程,但是使用多平台方法-如果可能,仅使用Java。 />
#1 楼
这是从命令“ 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();
}
如果使用Windows,则应更改以下行:进程p = Runtime.getRun ...”等(第3行),对于如下所示的文件:
Process p = Runtime.getRuntime().exec
(System.getenv("windir") +"\system32\"+"tasklist.exe");
希望信息对您有所帮助!
#2 楼
最后,在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
评论
应该添加哪些导入才能与ProcessHandle一起使用?
–乔尔迪
18年5月28日在16:35
该类在java.lang中,因此不需要导入
–Hugues M.
18年5月28日在16:42
#3 楼
在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);
}
}
评论
这仅给命令名称,而不是整个命令行。有没有办法获得整个命令行?
–克里斯托弗·丹西(Christopher Dancy)
13年5月4日在19:31
您可以通过调用GetModuleFileName获得完整路径。有关示例,请参见stackoverflow.com/questions/7521693/…。
–伊曼纽尔·布尔格(Emmanuel Bourg)
13年5月6日在8:29
唯一的问题是,它仅给出进程的路径,而不是整个命令行。有没有办法获取进程的完整命令行(即'ant.bat -f helloWorld.ext')?
–克里斯托弗·丹西(Christopher Dancy)
13年5月6日在16:31
如何检查xyz.exe之类的特定进程是否正在运行?
–位不明
13年7月5日在6:31
@ChristopherDancy不知道您是否仍需要答案,但是要确保完整性,而且这里也没有提到:Winodws管理信息命令行(或简称wmic.exe)提供了一种检索大量正在运行的应用程序信息的方法-WMIC PROCESS或限制特定过程的输出:WMIC PROCESS WHERE name ='theName'。如果需要,可以使用其他过滤器来限制输出。命令行包含在返回表的“命令行”列中(=第二列)
–罗马·沃特纳
2014年1月13日在13:51
#4 楼
我能想到的唯一方法是调用一个为您完成任务的命令行应用程序,然后对输出进行屏幕抓取(例如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
}
评论
是的,我也已经考虑过这一点,但是我坚决只能用Java做到这一点。而且我认为使用“ ps -aux”代替top会更好。感谢你及时的答复!
–拉玛亚克
08-09-10 at 17:04
在Windows上,可以将tasklist程序配置为输出CSV :)
– MauganRa
17 Mar 10 '17 at 8:41
#5 楼
YAJSW(还有另一个Java服务包装程序)看起来像它的org.rzo.yajsw.os.TaskList接口的基于JNA的实现,适用于win32,linux,bsd和solaris,并且已获得LGPL许可。我没有尝试直接调用此代码,但是当我过去使用YAJSW时,它的效果非常好,因此您不必担心太多。评论
显然v12 +是Apache / LGPL双重许可
– Harschware
2015年2月25日在0:18
#6 楼
您可以使用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("------------------");
}
评论
这个库似乎很慢...是有原因的(或者是跨vbs的通用java + wmi互操作吗?
–地精
16年4月18日在12:18
我猜您在谈论Windows实现。是的,通常WMI查询需要一些时间。与往常一样,这取决于用例。如果您需要每10毫秒执行一次查询,是的,它太慢了。
– profesor_falken
16-4-18的12:27
是的,我在谈论胜利,在Linux中我发现使用“ ps ...
–地精
16年4月18日在12:35
好的,如果您愿意,可以在github项目中创建一个问题,我最终将看一下是否可以提高Win的性能。实际上,我在Linux上使用了它,所以我没有过多注意赢得实现:-S
– profesor_falken
16年4月18日在12:43
很好,但是我一直在寻找:在您的流程startTime中,如果我没有记错,则将给定时间限制为一天(hh:mm:ss)。是否可以选择获取日期和时间(yyyy-mm-dd-hh:mm:ss)?
–地精
16-4-18在13:49
#7 楼
没有与平台无关的方法。在Java的1.6版本中,添加了“桌面”类,该类允许以可移植的方式浏览,编辑,邮寄,打开和打印URI。可能有一天有可能将该类扩展为支持进程,但是我对此表示怀疑。如果您仅对Java进程感到好奇,则可以使用java.lang.management api来获取线程/内存。有关JVM的信息。
#8 楼
对于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");
#9 楼
这对于捆绑了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");
}
#10 楼
最好选择使用代码来解析用于Linux的ps aux
和用于Windows的tasklist
,直到出现更通用的方法为止。对于Windows,您可以参考:http://www.rgagnon.com/javadetails/ java-0593.html Linux也可以通过
ps aux
传递grep
的结果,这将使处理/搜索变得快速而容易。我相信您也可以在Windows上找到类似的内容。评论
您可能还希望更详细地查看任务列表:technet.microsoft.com/zh-cn/library/bb491010.aspx
–詹姆斯·奥拉维克(James Oravec)
2012年5月17日15:46
#11 楼
下面的程序将仅与Java 9+版本兼容...要获取CurrentProcess信息,
public class CurrentProcess {
public static void main(String[] args) {
ProcessHandle handle = ProcessHandle.current();
System.out.println("Current Running Process Id: "+handle.pid());
ProcessHandle.Info info = handle.info();
System.out.println("ProcessHandle.Info : "+info);
}
}
对于所有正在运行的进程,
import java.util.List;
import java.util.stream.Collectors;
public class AllProcesses {
public static void main(String[] args) {
ProcessHandle.allProcesses().forEach(processHandle -> {
System.out.println(processHandle.pid()+" "+processHandle.info());
});
}
}
#12 楼
String line;
Process process = Runtime.getRuntime().exec("ps -e");
process.getOutputStream().close();
BufferedReader input =
new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((line = input.readLine()) != null) {
System.out.println(line); //<-- Parse data here.
}
input.close();
我们必须使用
process.getOutputStream.close()
,否则它将被锁定在while循环中。#13 楼
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“状态eq运行” / FO“ CSV” / FI“用户名eq LHPL002 \ soft” / FI“存储器gt 10000“ / FI” Windowtitle ne N / A“ / NH
#14 楼
这是我的函数代码,该函数获取任务并获取其名称,还将它们添加到列表中以从列表中进行访问。它使用数据创建临时文件,读取文件并获得带有.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();
}
评论
我还将这段代码制成了完整的程序,以尝试复制Windows 10的内置任务管理器,如果有兴趣的人,我可以向您发送演示。
–迪伦·韦德曼(Dylan Wedman)
18/12/29在1:53
评论
如何获得流程的开始时间和结束时间
–雄鹿
2012年9月11日上午9:27
在Windows上,运行tasklist.exe / fo csv / nh以CSV格式获取列表,这很容易解析。
–伊曼纽尔·布尔格(Emmanuel Bourg)
13年1月24日在15:31
但它没有显示jar名称。我的可执行jar名称是helloDemo.jar。但它没有显示任何东西
– Sumon Bappi
2015年5月2日,10:57
如果添加|为什么不起作用? grep java的?即ps -elf | grep java不会返回任何东西,但是ps -elf可以按预期工作。
– Itay Moav -Malimovka
16年5月2日在20:28
应该注意的是,底部的“特定于Windows”位似乎是不必要的。在Windows 10上,即使没有指定目录,(。exec(Runtime / getRuntime)“ tasklist”))(在Clojure中,使用Java-interop)也可以正确返回任务列表进程。
–致癌物质
17年1月9日,18:25