【问题标题】:Limit on commands for a ProcessBuilder?ProcessBuilder 的命令限制?
【发布时间】:2017-06-12 21:35:11
【问题描述】:

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;
    }

我开始怀疑实际代码是否有问题,而不是命令。

【问题讨论】:

  • 我认为限制是 cmd.exe
  • 我不确定为什么它不起作用,但我会亲自创建 commands = new ArrayList();然后是 pb.command(commands)。为什么首先要使用 cmd.exe?每当你 pb.start();运行命令还不够吗?还使用 pb.directory(new File(yourWorkingDir)); 指定工作目录;
  • @Krystian_K 命令是 cmd.exe 特定命令

标签: java swing processbuilder swingworker


【解决方案1】:

我认为您必须首先考虑的限制是命令本身的限制t(然后是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 问题中有所描述:

【讨论】:

  • 不确定是这个。开始怀疑整个 SwingWorker 代码是否有问题,因为当我不使用 SwingWorker 时它确实有效
【解决方案2】:

我认为您发送的整个命令对于 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();

【讨论】:

  • 那样它不会作为 cmd.exe 运行?
  • 另外,进程是否按照我添加的顺序执行这些命令?
  • 它确实运行 cmd 是的,并且它按照您添加它们的顺序运行它们。您也可以考虑等待 process.waitFor();在运行另一个命令之前执行一个命令。
  • 它不会为我通过 cmd 运行命令。这是我的代码:pastebin.com/FKdLCcLi
  • 尝试将“CMD”作为第一个命令,但因此您可能需要使用 /c,开始。我刚刚在这里尝试了一些简单的代码,效果很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-13
相关资源
最近更新 更多