Runtime.exec() 返回 null
Runtime.exec() returning null
我在这个网站上看到过类似的问题,但其中 none 似乎 address/solve 我的问题,所以我认为我的程序有问题。我正在尝试执行一个非常简单的命令,即从文本字段输入中获取进程名称的字符串并将其连接到 return 的命令并打印 window 的标题。这是我的代码:
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 编辑的行 return 始终为空,即使我将 .exec() 中使用的命令放入 cmd(我打印了它所以我知道它们完全相同) , 它工作正常,尽管延迟了 5 秒左右。我尝试使用 2 个不同的进程名称,它们都在 cmd 上工作,但在这个 java 程序中没有。这是上面代码的输出,以防万一(空白行可能来自命令字符串末尾的 \n):
tasklist /v /fo list /fi "imagename eq notepad*"| find /i "window title:"
done
我尝试在调用 .exec() 后添加 p.waitFor(),但这似乎没有任何改变。那么我在这里做错了什么?
您在启动命令时遇到了两个问题。首先,您忽略了错误流,因此看不到实际问题。
将 p = Runtime.getRuntime().exec(command);
替换为 ProcessBuilder
以访问错误消息:
ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectErrorStream();
p = pb.start();
这会告诉你 tasklist
不是一个进程。通常使用完整路径名可以修复此类错误,但是当您使用管道时,必须将整个命令发送到 CMD.EXE 才能正确解释管道组件。 运行 CMD.EXE 然后你的管道命令:
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
通过简单的传输也更容易读取 STDOUT:
try(var stdout = p.getInputStream()) {
stdout.transferTo(System.out); // or where-ever
}
我在这个网站上看到过类似的问题,但其中 none 似乎 address/solve 我的问题,所以我认为我的程序有问题。我正在尝试执行一个非常简单的命令,即从文本字段输入中获取进程名称的字符串并将其连接到 return 的命令并打印 window 的标题。这是我的代码:
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 编辑的行 return 始终为空,即使我将 .exec() 中使用的命令放入 cmd(我打印了它所以我知道它们完全相同) , 它工作正常,尽管延迟了 5 秒左右。我尝试使用 2 个不同的进程名称,它们都在 cmd 上工作,但在这个 java 程序中没有。这是上面代码的输出,以防万一(空白行可能来自命令字符串末尾的 \n):
tasklist /v /fo list /fi "imagename eq notepad*"| find /i "window title:"
done
我尝试在调用 .exec() 后添加 p.waitFor(),但这似乎没有任何改变。那么我在这里做错了什么?
您在启动命令时遇到了两个问题。首先,您忽略了错误流,因此看不到实际问题。
将 p = Runtime.getRuntime().exec(command);
替换为 ProcessBuilder
以访问错误消息:
ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectErrorStream();
p = pb.start();
这会告诉你 tasklist
不是一个进程。通常使用完整路径名可以修复此类错误,但是当您使用管道时,必须将整个命令发送到 CMD.EXE 才能正确解释管道组件。 运行 CMD.EXE 然后你的管道命令:
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
通过简单的传输也更容易读取 STDOUT:
try(var stdout = p.getInputStream()) {
stdout.transferTo(System.out); // or where-ever
}