【问题标题】:How to check if a process is running on Windows?如何检查一个进程是否在 Windows 上运行?
【发布时间】:2016-02-01 11:31:48
【问题描述】:

我正在尝试做的是一个程序来了解它是否在Windows 上处于活动状态的进程以在Java 中使用它。我上网查了一下,发现了两种不同的解决方案:

但这根本不是我想要的。

根据选项 1,我想要一种方法来引用该进程(并检测它是否处于活动/运行状态),但无需搜索完整的 tasklist 然后搜索它。我正在寻找是否有直接的方法来做到这一点。

我也向任务列表添加了一个过滤器,但找不到任何过滤器来仅获取我正在寻找的过程。我在命令行上看到了所有使用 tasklist /? 的选项。

然后我搜索了有关第二个选项和wmic(我以前从未听说过)的信息,似乎wmic 允许您在命令行上执行任务(如果我错了请纠正我)。

所以,我有两个问题:

  • 有没有直接的方法可以知道一个进程是否在 Windows 上使用 Java 处于活动状态?尽量避免在完整的任务列表中搜索或使用wmic。

  • 如果不可能,如果我们谈论高效编程,我在上面提出的两个选项中哪一个会更好?

提前致谢!

【问题讨论】:

  • 可以使用Java Native导入Process32Next()来枚举进程。例如:stackoverflow.com/q/9877993/1207195
  • 听起来你在这里设计了一个完整的假系统。你真正想解决什么问题?

标签: java windows process


【解决方案1】:

没有直接的方法来查询一般进程,因为每个操作系统处理它们的方式不同。
您有点坚持使用代理,例如直接操作系统命令...

但是,您可以使用带有 /fi 参数的 tasklist.exe 找到特定进程。
例如: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."

【讨论】:

  • 感谢您的回答。我现在要试试你的代码,但我有一些问题。您是否使用ArrayList,因为BufferedReader 还返回PID、控制台名称等...?而且,当您执行Runtime.getRuntime().exec(tasksCmd); 时,如果您已经运行了该进程。它创造了一个新的吗?再次感谢您!
  • 好的,你的代码我终于可以得到它,但我还有一个问题。你的代码最后一行的目的是什么?:Boolean processFound = procs... 如果我忽略它,代码就可以工作,但是如果我把它写出来,我的代码会给我一个异常,所以我认为这是不必要的。是吗?
  • 只有 Java8。您可以替换为查找所需文本的标准 for 循环。
  • 最后一行的目的是检查我们没有得到“信息:没有符合指定条件的任务正在运行。”。 (在这种情况下,数组有一些内容,但这不是必需的过程)。
  • 放个 throws Exception 一样吗?
【解决方案2】:

使用 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));

}

【讨论】:

  • 你从哪里得到 pid?如果您有 pid,则您已经知道该进程正在运行。
  • “isPresent()”和“get().isAlive()”有什么区别。 Imo "isPresent()" 就足够了,因为当进程不存在时它也会返回 false。有什么难处吗?
【解决方案3】:

最好的方法是从 java 实例启动进程。这种方法的优点是您可以完全确定正在运行的进程就是您启动的进程。使用tasklist,普通用户可以启动以名称为目标的进程,或者在程序关闭时重用pid。

有关如何启动进程的信息,请参阅this 问题。

Process myProcess = Runtime.getRuntime().exec(command);

然后您可以使用 Process 的方法来监视程序的状态,例如 myProcess.exitValue() 阻塞直到程序关闭。

【讨论】:

  • 是的,这正是我正在寻找的,但在不自己执行该过程的情况下尝试做到这一点。我知道我有一个进程处于活动状态,并希望将其存储在 Process 变量中,就像您在示例中一样。这是一种方法,但没有从任务列表中获取所有进程数组?
  • 如果进程启动另一个进程并关闭另一个进程,则无法确定它是否处于活动状态。这种方法是有缺陷的。
猜你喜欢
  • 2011-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-28
  • 1970-01-01
  • 1970-01-01
  • 2019-11-28
  • 2014-06-24
相关资源
最近更新 更多