我想做的是一个程序来了解它是否在
Windows
上处于活动状态,以便在 Java
中使用它。我上网查了一下,发现了两种不同的解决方案:
但这根本不是我想要的。
根据选项1,我想要一种方法来引用该进程(并检测它是否处于活动/正在运行),但无需在完整的
tasklist
中搜索,然后对其进行搜索。我正在寻找是否有直接的方法可以做到这一点。
我还想向任务列表添加一个过滤器,但找不到任何过滤器来仅获取我正在寻找的进程。我在命令行上使用
tasklist /?
看到了所有选项。
然后我搜索了有关第二个选项和
wmic
(我以前从未听说过)的信息,似乎wmic
允许您在命令行上执行任务(如果我错了请纠正我)。
所以,我有两个问题:
有没有直接的方法可以用Java知道Windows上的进程是否处于活动状态?尽量避免在完整任务列表中搜索或使用
wmic
。如果不可能,如果我们谈论高效编程,我上面提出的两个选项中哪个会更好?
提前致谢!
没有直接的方法来查询一般进程,因为每个操作系统对它们的处理方式不同。
您有点坚持使用代理,例如直接操作系统命令......
但是,您可以使用带有 /fi 参数的 tasklist.exe 查找特定进程。
例如:
tasklist.exe /nh /fi "Imagename eq chrome.exe"
同样的示例,在 Java 中过滤“chrome.exe”:
String findProcess = "chrome.exe";
String filenameFilter = "/nh /fi \"Imagename eq "+findProcess+"\"";
String tasksCmd = System.getenv("windir") +"/system32/tasklist.exe "+filenameFilter;
Process p = Runtime.getRuntime().exec(tasksCmd);
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
ArrayList<String> procs = new ArrayList<String>();
String line = null;
while ((line = input.readLine()) != null)
procs.add(line);
input.close();
Boolean processFound = procs.stream().filter(row -> row.indexOf(findProcess) > -1).count() > 0;
// Head-up! If no processes were found - we still get:
// "INFO: No tasks are running which match the specified criteria."
使用 Java 9,你可以这样做:
Optional<ProcessHandle> processHandle = ProcessHandle.of(pid);
boolean isrunning = processHandle.isPresent() && processHandle.get().isAlive();
您现在还可以直接使用 java 获取有关进程的一些信息。
Optional<ProcessHandle> processHandle = ProcessHandle.of(pid);
if(processHandle.isPresent()) {
ProcessHandle.Info processInfo = processHandle.get().info();
System.out.println("COMMAND: " + processInfo.command().orElse(""));
System.out.println("CLI: " + processInfo.commandLine().orElse(""));
System.out.println("USER: " + processInfo.user().orElse(""));
System.out.println("START TIME: " + processInfo.startInstant().orElse(null));
System.out.println("TOTAL CPU: " + processInfo.totalCpuDuration().orElse(null));
}
最好的方法是从 java 实例启动进程。这种方法的优点是您可以完全确定正在运行的进程是您启动的进程。使用任务列表,普通用户可以启动一个以名称为目标的进程,或者在程序关闭时重用 pid。
有关如何启动流程的信息,请参阅this问题。
Process myProcess = Runtime.getRuntime().exec(command);
然后您可以使用 Process 的方法来监视程序的状态,例如
myProcess.exitValue()
会阻塞,直到程序关闭。
您可以使用Java 9轻松实现这样的方法:
public boolean isProcessRunning(String processName)
{
return ProcessHandle
.allProcesses()
.filter(p -> p.info().command().isPresent())
.anyMatch(n -> n.info().command().orElse("").endsWith(processName));
}
注意:我使用了
endsWith(..)
,因为该命令包含执行文件的完整路径。顺便说一句,如果你有 PID,请查看已接受的答案。