【问题标题】:To check whether an application is running or not using java?使用 java 检查应用程序是否正在运行?
【发布时间】:2015-06-04 08:01:19
【问题描述】:

我有一个 java 应用程序在后台启动另一个 java 应用程序(第三方),所以在启动第三方后台应用程序之前,我想检查该应用程序是否已经在运行(不想等待终止该应用程序)。
我正在使用以下代码来启动第三方 java 应用程序:

String path = new java.io.File("do123-child.cmd").getCanonicalPath();
Runtime.getRuntime().exec(path);

注意:文件“do123-child.cmd”调用“.bat”文件来运行该应用程序。

要检查给定的应用程序是否正在运行,我使用以下代码 [Ref link]:

boolean result = false;
try {
    String line;
    Process p = Runtime.getRuntime().exec("tasklist.exe");
    BufferedReader input =
            new BufferedReader(new InputStreamReader(p.getInputStream()));
    while ((line = input.readLine()) != null) {
        if(line.startsWith("myApp.exe")){
            result = true;
            break;
        }
     }
     input.close();
} catch (Exception err) {
     err.printStackTrace();
}
return result;

我想知道是否有其他方法可以在不迭代当前正在运行的所有进程的情况下做到这一点?喜欢:

Process p = Runtime.getRuntime().exec("tasklist /FI \"IMAGENAME eq myApp.exe\" /NH");
int exitVal = p.exitValue();
//if above code throw "java.lang.IllegalThreadStateException" means application is running.

但以上代码为所有应用程序返回 0。

提前致谢。

【问题讨论】:

  • @MichaelLaffargue :在给定的链接(由你)代码中等待进程/应用程序的终止,但在我的场景中我不想等待应用程序的终止,我只是想知道应用程序是否正在运行。
  • 我的坏@Bhushan。 tasklist 是在 Windows 上的方式(除非你想使用 JNA
  • @MichaelLaffargue :实际上我不想使用 JNA 因为我的应用程序同时适用于 windows 和 MAC ,上面的代码将适用于两者,只是我必须将命令 "tasklist.exe" 更改为特定于 mac , 表示命令将根据操作系统类型决定,但逻辑相似(尚未在 MAC 上尝试过此代码)。

标签: java windows process


【解决方案1】:

您可以使用jps 来检查正在运行的Java 应用程序。 jps 与 JRE 捆绑在一起。

jps -l
19109 sun.tools.jps.Jps
15031 org.jboss.Main
14040 
14716

您可以使用 Runtime.getRuntime().exec()reading the input stream 从该程序中抓取列表,然后在 Java 中搜索包名称以查找匹配项。

由于您想避免迭代所有结果,您可以使用 findstr grep 结果以返回您正在寻找的基本 p.exitValue() 结果:

Process p = Runtime.getRuntime().exec("jps -l | findstr /R /C:\"com.myapp.MyApp\"");
int exitVal = p.exitValue(); // Returns 0 if running, 1 if not

当然,findstr 是特定于 Windows 的,因此您需要在 Mac 上使用 grep

Process p = Runtime.getRuntime().exec("jps -l | grep \"com.myapp.MyApp\"");
int exitVal = p.exitValue(); // Returns 0 if running, 1 if not

jps 工具使用内部 API (MonitoredHost) 来获取此信息,因此您也可以完全在 Java 中执行此操作:

String processName = "com.myapp.MyApp";

boolean running = false;
HostIdentifier hostIdentifier = new HostIdentifier("local://localhost");

MonitoredHost monitoredHost;
monitoredHost = MonitoredHost.getMonitoredHost(hostIdentifier);

Set activeVms = monitoredHost.activeVms();
for (Object activeVmId : activeVms) {
    VmIdentifier vmIdentifier = new VmIdentifier("//" + String.valueOf(activeVmId) + "?mode=r");
        MonitoredVm monitoredVm = monitoredHost.getMonitoredVm(vmIdentifier);
    if (monitoredVm != null) {
        String mainClass = MonitoredVmUtil.mainClass(monitoredVm, true);
        if (mainClass.toLowerCase().equals(processName.toLowerCase())) {
            running = true;
            break;
        }
    }
}

System.out.print(running);

【讨论】:

  • 只使用JVM进程不是吗?这就是 OP 想要的,只是为了完善我的知识。
  • 是的,这只适用于 JVM 进程。如果您想监控非 Java 应用程序,则需要使用不同的解决方案。
  • @seanhodges:我对 String processName = "com.myapp.MyApp"; 是否 "com.myapp.MyApp" 是 ImageName 或 Class name 感到困惑?如果是类名,那么我怎么知道另一个 java 应用程序(第三方)的类名?
  • 这很简单。我上面的示例显示了“org.jboss.Main”,它表示一个 JBoss 实例。如果包名称不明显,则在应用程序关闭然后打开的情况下运行 jps -l - 新进程将在第一个列表中丢失,但在第二个列表中可见。
猜你喜欢
  • 1970-01-01
  • 2019-02-16
  • 2016-07-17
  • 1970-01-01
  • 2011-06-10
  • 2014-09-26
  • 1970-01-01
  • 1970-01-01
  • 2017-03-08
相关资源
最近更新 更多