【问题标题】:Read from already open CMD - java从已经打开的 CMD 中读取 - java
【发布时间】:2017-09-08 00:04:20
【问题描述】:

无论如何,Java 应用程序是否可以从已经打开的 CMD 窗口中读取。例如,我打开了一个 cmd,运行“dir”,然后决定运行我的应用程序,我的应用程序有什么方法可以读取已经在打开的 CMD 窗口中的信息而不打开另一个? 提前致谢

更新: 我希望当一个 java 应用程序运行时,它会检查任何当前打开的 CMD 窗口,以确保我的另一个命令行应用程序在它自己打开之前没有运行。

【问题讨论】:

  • 可能不会——你能解释一下你为什么需要它吗?可能还有其他方法。
  • 你不能。但是您可以在 java 中使用 ProcessBuilder 运行 dir commnad 并使用其输出流来读取内容。
  • @RajeevSreedharan 感谢您的回复,我确实知道从 ProcessBuilder 读取的能力。我希望当一个 java 应用程序运行时,它会检查任何当前打开的 CMD 窗口,以确保我的另一个命令行应用程序在它自己打开之前没有运行。
  • @John.Smith 其他应用程序还在运行吗?在这种情况下,您可以检查正在运行的进程。如果没有,您可能有一个文件或数据库来指示上次运行或类似的东西。
  • @assylias 应用程序将检查另一个是否仍在运行以上问题)。我可能不得不使用您建议的替代文件,谢谢。

标签: java command-line cmd


【解决方案1】:

只需将已执行命令的输出假脱机到一个文件中。

例如:做dir > spool.txt 并从 java 程序中打开带有FileInputStreamspool.txt 文件。

为了确保内容在阅读之前完全写好,您可以例如:

  • 在写入的文件中使用标记来表示
  • 检查写入文件的修改日期(如果在规定的时间内修改日期没有变化,则可能是写入完成的信号)

更新问题:检查 CMD 窗口是否打开

更新:我希望当运行一个 java 应用程序时,它会 检查任何当前打开的 CMD 窗口,以确保另一个 我的命令行应用程序在打开之前没有运行 自己。

您可以使用tasklist.exe 程序简单地列出Windows 正在运行的进程。
信息按进程一行检索。
然后,检查其中一行是否以 cmd.exe 开头。
如果是这种情况,则意味着cmd.exe 程序已经在运行。

这是一个示例代码;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class CmdProcessSearch {

    public static void main(String[] args) throws IOException {
        boolean anyCmdProgramOpened = isAnyCmdProgramOpened();
        System.out.println("isOpened = " + anyCmdProgramOpened);
    }
    public static boolean isAnyCmdProgramOpened() {
        Process p;
        try {
            p = Runtime.getRuntime().exec(System.getenv("windir") + "\\system32\\" + "tasklist.exe");
            String line;
            BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
            while ((line = input.readLine()) != null) {
                System.out.println(line);
                if (line.startsWith("cmd.exe")) {
                    return true;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }
}

C:\windows\system32 通常在 PATH 环境变量中。
所以,p = Runtime.getRuntime().exec("tasklist.exe"); 应该足够了 但为了防止任何副作用或错误配置问题,最好指定绝对路径。


带有新评论的新更新:检查 Java 应用程序是否正在运行

我已将此代码用于不同的部分,但如果有 cmd 窗口运行,不保证用户已经用它运行 我的程序,打包过程;

在这种情况下,如果您可以在客户端计算机上安装 jdk 工具,您可以检查是否正在使用作为主类(应用程序的主类)运行 Java 进程。
你可以使用jps (Java Virtual Machine Process Status Tool)。

这里是可用的选项:

选项

jps 命令支持许多修改 命令的输出。这些选项可能会更改或删除 未来。

-q

抑制传递给 main 方法的类名、JAR 文件名和参数的输出,只生成本地 VM 的列表 标识符。

-m

输出传递给主方法的参数。对于嵌入式 JVM,输出可能为空。

-l

输出应用程序主类的完整包名或应用程序 JAR 文件的完整路径名。

-v

输出传递给 JVM 的参数。

-V

通过flags文件(.hotspotrc文件或者-XX:Flags=指定的文件)输出传递给JVM的参数 论据)。

-选择选项

将选项传递给 jps 调用的 java 启动器。例如,-J-Xms48m 将启动内存设置为 48 兆字节。 -J 将选项传递给正在执行的底层虚拟机是一个常见的约定 用 Java 编写的应用程序。

jps -l 命令输出应用程序主类的完整包名或应用程序 JAR 文件的完整路径名。

下面是搜索应用主类process.JavaProcessSearch的示例代码:

package process;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class JavaProcessSearch {

    public static void main(String[] args) throws IOException {
        boolean isProcessRunning = isAJavaProcessWithMainClass("process.JavaProcessSearch");
        System.out.println(isProcessRunning);
    }

    public static boolean isAJavaProcessWithMainClass(String mainClass) {
        Process p;
        try {
             String javaHome = System.getenv("JAVA_HOME");
             p = Runtime.getRuntime().exec(javaHome + File.separator + "bin/jps -l");

            String line;
            BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
            while ((line = input.readLine()) != null) {
                System.out.println(line);
                if (line.contains(mainClass)) {
                    return true;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return false;
    }

}

如果您无法安装 jdk 工具,您可以在客户端计算机上存储“某处”,即应用程序启动时的进程 ID。 您可以使用以下方法检索此信息:ManagementFactory.getRuntimeMXBean().getName()
当它不再运行(停止或崩溃)时,您可以删除此进程 ID 信息。
当应用程序启动时,如果在客户端计算机上检索到进程 ID,则不允许应用程序启动。
对于停止的应用程序情况,关闭挂钩应该可以完成这项工作。
对于崩溃的应用情况,您可以使用守护线程定期检查应用程序是否始终运行,这取决于存储的进程 ID。

【讨论】:

  • 抱歉,示例有误导性,请查看更新
  • 我已经将此代码用于不同的部分,但是如果有一个 cmd 窗口正在运行,则不能保证用户已经使用它来运行我的程序,因为我知道他们在早一点,只是没有关闭窗口。
  • 在这种情况下,您只需检查您的程序是否使用jps -l 运行。我更新了新代码。
  • 所以用你新提供的代码,我只需要把“process.JavaProcessSearch”改成“包名类名”?
  • 另外我有一个错误“无法运行程序'jps'”我假设这与“PATH”的配置方式有关,这意味着我可能无法使用它,因为我将无法保证用户的计算机已正确配置“PATH”
猜你喜欢
  • 1970-01-01
  • 2015-03-15
  • 1970-01-01
  • 2019-06-19
  • 2013-11-01
  • 2015-10-21
  • 2012-06-09
  • 2015-04-06
  • 1970-01-01
相关资源
最近更新 更多