如何检查进程是否在 Windows 上 运行?
How to check if a process is running on Windows?
我正在尝试做的是一个程序,用于了解它在 Windows
上是否处于活动状态以便在 Java
中使用它。我在网上看了看,发现了两种不同的解决方案:
- Option 1
- Option 2
但这根本不是我要找的。
根据选项 1,我想要一种方法来引用该过程(并检测它是否为 active/running)但无需完整搜索 tasklist
然后在其上搜索.我正在寻找是否有直接的方法来做到这一点。
我也想在任务列表中添加一个过滤器,但找不到任何过滤器来只获取我正在寻找的进程。我在命令行上使用 tasklist /?
看到了所有选项。
然后我搜索了关于第二个选项和wmic
(我以前从未听说过)的信息,似乎wmic
允许你在命令行上执行任务(如果我是,请纠正我请错了)。
所以,我有两个问题:
是否有直接方法可以知道 Windows 和 Java 上的进程是否处于活动状态?尽量避免在完整任务列表中搜索或使用 wmic
.
如果不可能,如果我们谈论高效编程,我上面提出的两个选项哪个更好?
提前致谢!
最好的方法是从 java 实例启动进程。这种方法的优点是你可以完全确定 运行 的进程就是你启动的进程。使用tasklist,普通用户可以启动一个以name为目标的进程,或者在程序关闭时重用pid。
有关如何启动进程的信息,请参阅 this 问题。
Process myProcess = Runtime.getRuntime().exec(command);
然后您可以使用 Process 的方法来监视程序的状态,例如 myProcess.exitValue()
阻塞直到程序关闭。
没有直接的方法来查询一般流程,因为每个 OS 处理它们的方式不同。
您有点坚持使用代理,例如直接 OS 命令...
您 可以 但是,使用 tasklist.exe 和 /fi 参数找到特定进程。
例如:tasklist.exe /nh /fi "Imagename eq chrome.exe"
请注意强制性双引号。
MS Technet site.
上提供了语法和用法
同样的例子,在 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));
}
我正在尝试做的是一个程序,用于了解它在 Windows
上是否处于活动状态以便在 Java
中使用它。我在网上看了看,发现了两种不同的解决方案:
- Option 1
- Option 2
但这根本不是我要找的。
根据选项 1,我想要一种方法来引用该过程(并检测它是否为 active/running)但无需完整搜索 tasklist
然后在其上搜索.我正在寻找是否有直接的方法来做到这一点。
我也想在任务列表中添加一个过滤器,但找不到任何过滤器来只获取我正在寻找的进程。我在命令行上使用 tasklist /?
看到了所有选项。
然后我搜索了关于第二个选项和wmic
(我以前从未听说过)的信息,似乎wmic
允许你在命令行上执行任务(如果我是,请纠正我请错了)。
所以,我有两个问题:
是否有直接方法可以知道 Windows 和 Java 上的进程是否处于活动状态?尽量避免在完整任务列表中搜索或使用
wmic
.如果不可能,如果我们谈论高效编程,我上面提出的两个选项哪个更好?
提前致谢!
最好的方法是从 java 实例启动进程。这种方法的优点是你可以完全确定 运行 的进程就是你启动的进程。使用tasklist,普通用户可以启动一个以name为目标的进程,或者在程序关闭时重用pid。
有关如何启动进程的信息,请参阅 this 问题。
Process myProcess = Runtime.getRuntime().exec(command);
然后您可以使用 Process 的方法来监视程序的状态,例如 myProcess.exitValue()
阻塞直到程序关闭。
没有直接的方法来查询一般流程,因为每个 OS 处理它们的方式不同。
您有点坚持使用代理,例如直接 OS 命令...
您 可以 但是,使用 tasklist.exe 和 /fi 参数找到特定进程。
例如:tasklist.exe /nh /fi "Imagename eq chrome.exe"
请注意强制性双引号。
MS Technet site.
同样的例子,在 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));
}