ProcessBuilder上的命令是否有限制?
我有这个命令数组:
protected String[] cmd = {
"dism /mount-wim /wimfile:boot.wim /index:2 /mountdir:mount",
"dism /image:mount /add-driver:\"driver\" /recurse",
"dism /unmount-wim /mountdir:mount /commit",
"dism /mount-wim /wimfile:install.wim /index:" + formPanel.getOsIndex() + " /mountdir:mount"
};
这是我的ProcessBuilder:
ProcessBuilder pb = new ProcessBuilder(
"cmd.exe", "/c", cmd[0] + " && " + cmd[1] + " && " + cmd[2] + " && " + cmd[3] + " && " + cmd[1] + " && " + cmd[2]
);
但是,当我运行它时,它说'&&这时出乎意料'。当我将processbuilder改为:
ProcessBuilder pb = new ProcessBuilder(
"cmd.exe", "/c", cmd[0] + " && " + cmd[1] + " && " + cmd[2]
);
然后它工作正常。
所以我的问题基本上就是对某个流程制造商可以通过多少命令的限制?
这是我的SwingWorker方法的整个部分:
@Override
protected Integer doInBackground() {
try {
ProcessBuilder pb = new ProcessBuilder(
"cmd.exe", "/c", cmd[0] + " && " + cmd[1] + " && " + cmd[2] + " && " + cmd[3] + " && " + cmd[1] + " && " + cmd[2]
);
pb.directory(new File(formPanel.workspaceDir.toString()));
pb.redirectErrorStream(true);
Process p = pb.start();
String s;
BufferedReader stdout = new BufferedReader(new InputStreamReader(p.getInputStream()));
while((s = stdout.readLine()) != null && !isCancelled()) {
publish(s);
System.err.println(s);
}
if(!isCancelled()) {
status = p.waitFor();
}
p.getInputStream().close();
p.getOutputStream().close();
p.getErrorStream().close();
p.destroy();
} catch(IOException | InterruptedException ex) {
ex.printStackTrace(System.err);
}
return status;
}
我开始怀疑实际代码是否有问题,而不是命令。
答案 0 :(得分:3)
我认为首先要考虑的限制是命令itselft的限制(然后是ProcessBuilder
),如果您使用的是Windows或Unix,则会有所不同。
对于Windows,根据"Command prompt (Cmd. exe) command-line string limitation" documentation:
在运行Microsoft Windows XP或更高版本的计算机上,最大长度 您可以在命令提示符处使用的字符串是8191 字符。在运行Microsoft Windows 2000或Windows NT的计算机上 4.0,您可以在命令提示符处使用的字符串的最大长度为2047个字符。
此限制适用于命令行,个别环境 其他继承的变量(如PATH变量) 进程和所有环境变量扩展。如果您使用命令 提示运行批处理文件,此限制也适用于批处理文件 处理
对于Unix,我建议你参考以下解决的Stackoverflow问题:
此外,您应该考虑Java中数组的限制大小,这将在下面的Stackoverflow问题中描述:
答案 1 :(得分:0)
我认为您发送的整个命令对于cmd.exe来说可能太长了,因为您在使用Runtime.exec()时使用了可执行文件;或类似的东西?
List<String> commands = new ArrayList<>();
final ProcessBuilder builder = new ProcessBuilder();
commands.add("dism /mount-wim /wimfile:boot.wim /index:2 /mountdir:mount");
依此类推,另外我不确定你是否可以在这里有空格,或者你需要将所有内容添加为单独的命令。
builder.command(commands);
builder.directory(new File(workingDir));
process = builder.start();