Runtime.exec() 返回 null

问题描述

在这个网站上看到过类似的问题,但似乎没有一个解决/解决我的问题,所以我认为我的程序有问题。我正在尝试执行一个非常简单的命令,即从文本字段输入中获取进程名称的字符串并将其连接到命令以返回并打印窗口的标题。这是我的代码

        String line;
        Process p = null;
        try
        {
            String command = "tasklist /v /fo list /fi \"imagename eq  " + tf.getText().trim() + "*\"| find /i  \"window title:\"\n";
            p = Runtime.getRuntime().exec(command);

            BufferedReader input =
                    new BufferedReader(new InputStreamReader(p.getInputStream()));

            System.out.println(command);
            while ((line = input.readLine()) != null)
            {
                line = line.trim();
                System.out.println(line);

            }
            System.out.println("done");
        }
        catch (IOException ioException)
        {
            ioException.printstacktrace();
        }

但是,InputStream 返回的行始终为空,即使我将 .exec() 中使用的命令放入 cmd(我打印它以便我知道它们完全相同),它也可以正常工作,尽管在5 秒左右的延迟。我尝试了 2 个不同的进程名称,它们都在 cmd 上工作,但不在这个 java 程序中。这是上述代码输出,以防万一(空行可能来自命令字符串末尾的 \n):

tasklist /v /fo list /fi "imagename eq  notepad*"| find /i  "window title:"

done

我尝试在调用 .exec() 后添加 p.waitFor(),但这似乎没有任何改变。那么我在这里做错了什么?

解决方法

您在启动命令时遇到了两个问题。首先,您忽略了错误流,因此看不到实际问题。

2021-04-27 08:59:57,336 [ 416653] INFO - cloudConfig.CloudConfigManager - === Start.Edit: [colors.scheme.xml] |false| === 2021-04-27 08:59:57,336 [ 416653] INFO - cloudConfig.CloudConfigManager - === Start.Edit: [laf.xml] |true| === 2021-04-27 08:59:58,352 [ 417669] INFO - cloudConfig.CloudConfigManager - === doConnect === 2021-04-27 08:59:58,352 [ 417669] INFO - cloudConfig.CloudConfigManager - === getConnectionState === 2021-04-27 08:59:59,433 [ 418750] INFO - cloudConfig.CloudConfigManager - === End.Update: [C:\Users\user_name\AppData\Roaming\JetBrains\PyCharm2021.1\jba_config\colors.scheme.xml,C:\Users\user_name\AppData\Roaming\JetBrains\PyCharm2021.1\jba_config\laf.xml] === 替换为 p = Runtime.getRuntime().exec(command); 以获取错误消息:

ProcessBuilder

这将告诉您 ProcessBuilder pb = new ProcessBuilder(command); pb.redirectErrorStream(); p = pb.start(); 不是一个进程。通常使用完整路径名会修复这种类型的错误,但是当您使用管道时,整个命令必须发送到 CMD.EXE 才能正确解释管道组件。运行 CMD.EXE 然后你的管道命令:

tasklist

打印:

ProcessBuilder pb = new ProcessBuilder("cmd.exe","/c",command);
pb.redirectErrorStream();
p = pb.start();

通过简单的传输也更容易阅读标准输出:

tasklist /v /fo list /fi "imagename eq  notepad*"| find /i  "window title:"

Window Title: Notepad++
done

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...