【问题标题】:Java, Checking if any process ID is currently running on WindowsJava,检查是否有任何进程 ID 当前在 Windows 上运行
【发布时间】:2011-02-01 19:15:26
【问题描述】:

是否可以在 Windows 中检查 Java 进程是否存在。

我有它可能的 PID,我想知道它是否还在运行。

【问题讨论】:

标签: java windows pid


【解决方案1】:

如何使用 Java 检查 pid 是否在 Windows 上运行:

Windows 任务列表命令:

DOS 命令tasklist 显示有关正在运行的进程的一些输出:

C:\Documents and Settings\eric>tasklist

Image Name                   PID Session Name     Session#    Mem Usage
========================= ====== ================ ======== ============
System Idle Process            0 Console                 0         28 K
System                         4 Console                 0        244 K
smss.exe                     856 Console                 0        436 K
csrss.exe                    908 Console                 0      6,556 K
winlogon.exe                 932 Console                 0      4,092 K
....
cmd.exe                     3012 Console                 0      2,860 K
tasklist.exe                5888 Console                 0      5,008 K

C:\Documents and Settings\eric>

第二列是PID

您可以使用tasklist 获取有关特定 PID 的信息:

tasklist /FI "PID eq 1300"

打印:

Image Name                   PID Session Name     Session#    Mem Usage
========================= ====== ================ ======== ============
mysqld.exe                  1300 Console                 0     17,456 K

C:\Documents and Settings\eric>

响应意味着 PID 正在运行。

如果你查询一个不存在的 PID,你会得到:

C:\Documents and Settings\eric>tasklist /FI "PID eq 1301"
INFO: No tasks running with the specified criteria.
C:\Documents and Settings\eric>

Java 函数可以自动完成上述工作

此功能仅适用于有tasklist 可用的Windows 系统。

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

public class IsPidRunningTest {

    public static void main(String[] args) {

        //this function prints all running processes
        showAllProcessesRunningOnWindows();

        //this prints whether or not processID 1300 is running
        System.out.println("is PID 1300 running? " + 
            isProcessIdRunningOnWindows(1300));

    }

    /**
     * Queries {@code tasklist} if the process ID {@code pid} is running.
     * @param pid the PID to check
     * @return {@code true} if the PID is running, {@code false} otherwise
     */
    public static boolean isProcessIdRunningOnWindows(int pid){
        try {
            Runtime runtime = Runtime.getRuntime();
            String cmds[] = {"cmd", "/c", "tasklist /FI \"PID eq " + pid + "\""};
            Process proc = runtime.exec(cmds);

            InputStream inputstream = proc.getInputStream();
            InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
            BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
            String line;
            while ((line = bufferedreader.readLine()) != null) {
                //Search the PID matched lines single line for the sequence: " 1300 "
                //if you find it, then the PID is still running.
                if (line.contains(" " + pid + " ")){
                    return true;
                }
            }

            return false;
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("Cannot query the tasklist for some reason.");
            System.exit(0);
        }

        return false;

    }

    /**
     * Prints the output of {@code tasklist} including PIDs.
     */
    public static void showAllProcessesRunningOnWindows(){
        try {
            Runtime runtime = Runtime.getRuntime();
            String cmds[] = {"cmd", "/c", "tasklist"};
            Process proc = runtime.exec(cmds);
            InputStream inputstream = proc.getInputStream();
            InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
            BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
            String line;
            while ((line = bufferedreader.readLine()) != null) {
                System.out.println(line);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("Cannot query the tasklist for some reason.");
        }
    }
}

上面的 Java 代码打印所有正在运行的进程的列表,然后打印:

is PID 1300 running? true

【讨论】:

    【解决方案2】:

    看看这是否有帮助:

    http://blogs.oracle.com/vaibhav/entry/listing_java_process_from_java

    那篇文章解释了如何让所有 PID 在 Windows 机器上运行:您必须将 cmd 调用的输出与您的 PID 进行比较,而不是打印出来。

    如果您使用的是类 Unix 系统,则必须使用 ps 而不是 cmd

    从您的 java 代码调用系统命令不是一个非常便携的解决方案;再说一遍,进程的实现因操作系统而异。

    【讨论】:

      【解决方案3】:

      代码:

      boolean isStillAllive(String pidStr) {
          String OS = System.getProperty("os.name").toLowerCase();
          String command = null;
          if (OS.indexOf("win") >= 0) {
              log.debug("Check alive Windows mode. Pid: [{}]", pidStr);
              command = "cmd /c tasklist /FI \"PID eq " + pidStr + "\"";
              return isProcessIdRunning(pidStr, command);
          } else if (OS.indexOf("nix") >= 0 || OS.indexOf("nux") >= 0) {
              log.debug("Check alive Linux/Unix mode. Pid: [{}]", pidStr);
              command = "ps -p " + pidStr;
              return isProcessIdRunning(pidStr, command);
          }
          log.debug("Default Check alive for Pid: [{}] is false", pidStr);
          return false;
      }
      
      
      boolean isProcessIdRunning(String pid, String command) {
          log.debug("Command [{}]",command );
          try {
              Runtime rt = Runtime.getRuntime();
              Process pr = rt.exec(command);
      
              InputStreamReader isReader = new InputStreamReader(pr.getInputStream());
              BufferedReader bReader = new BufferedReader(isReader);
              String strLine = null;
              while ((strLine= bReader.readLine()) != null) {
                  if (strLine.contains(" " + pid + " ")) {
                      return true;
                  }
              }
      
              return false;
          } catch (Exception ex) {
              log.warn("Got exception using system command [{}].", command, ex);
              return true;
          }
      }
      

      【讨论】:

        【解决方案4】:
        1. 将 jna 从 Maven 导入到您的项目中
        2. maven 更新后,您可以使用:

        int myPid = Kernel32.INSTANCE.GetCurrentProcessId();

        【讨论】: