1

我正在尝试从 java 应用程序调用 .bat 文件。看起来很简单,但我有两个问题,非常感谢一些建议:

  1. 下面的代码无法执行 bat 文件,因为参数字符串超过 94 个字符。如果我正好使用 94 个字符(通过从clientArgs字符串末尾删除尾随的“x”),bat 文件执行正常。
    (如果我使用替代调用并将 args 传递为同样的问题String[]
    无论如何,我需要能够传递更长的命令字符串(~150 个字符)

  2. 如果我修改clientArgs为不包括完整的文件名,而只包括短名称(因为我指定了工作目录),我得到:

    java.io.IOException: Cannot run program "client.bat" (in directory "C:\2\code\FlaFl\flafl-0.7-RC2"): CreateProcess error=2, The system cannot find the file specified

这是代码:

public static void main(String[] args) {  
    String CMD_FILE_NAME = "client.bat"; //cmd or bat - still limit'n is 94 chars
    String cmdFileFolder= "C:/2/code/FlaFl/flafl-0.7-RC2/"; 
    File workingDir = new File(cmdFileFolder);
    String clientArgs = cmdFileFolder + 
         CMD_FILE_NAME + " -host name12.mycompanyname3.com -app hive"
         + "123456789 34x";  //95 chars fails. remove the x to get it to work
    System.out.println("length of invoc str is "+clientArgs.length());
    Process process=null;
    try {
         process = Runtime.getRuntime().exec(clientArgs,null,workingDir);
    } catch (IOException e) {
         System.out.println("exception "+e);
    }
    //sleep(2000);
    //if (process!=null)
    //    process.destroy();
}
4

4 回答 4

1

来自http://en.wikipedia.org/wiki/COMMAND.COM

交互模式下的命令行长度限制为 126 个字符。

这可能是您的问题的原因。

您可以创建一个.bat文件并运行它。

于 2012-08-21T12:04:18.820 回答
1

Exec 的 Java Doc 建议

ProcessBuilder.start() 现在是使用修改后的环境启动进程的首选方式。

于 2012-08-21T12:04:38.417 回答
0

尝试使用以下代码:

public static void main(String[] args) {
    String CMD_FILE_NAME = "client.bat"; // cmd or bat - still limit'n is 94
                                            // chars
    String cmdFileFolder = "C:/2/code/FlaFl/flafl-0.7-RC2/";
    File workingDir = new File(cmdFileFolder);
    String clientArgs = CMD_FILE_NAME
            + " -host name12.mycompanyname3.com -app hive"
            + "123456789 34x"; // 95 chars fails. remove the x to get it to
                                // work
    System.out.println("length of invoc str is " + clientArgs.length());
    Process process = null;
    try {
        process = Runtime.getRuntime().exec(clientArgs, null, workingDir);
    } catch (IOException e) {
        System.out.println("exception " + e);
    }
    // sleep(2000);
    // if (process!=null)
    // process.destroy();
}

cmdFileFolder当您传递workingDirRuntime.exec()方法时,您正在给出命令,即代码中的工作目录。

于 2012-08-21T12:08:32.303 回答
0

试图复制您的问题,我成功地运行了具有更长得多的参数行的命令。
尝试插入

  try {
        p.waitFor();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

在你执行你的命令(代替那些被评论的sleep() ...)以确保你允许它完成之后。

这种方法实际上还有另一个问题(我最初认为这可能是您的问题) - 如果您的进程写入足够的数据来填充它的控制台缓冲区,它可能会阻塞,如此处所述(用于进程的 javadoc):

由于部分原生平台只为标准输入输出流提供有限的缓冲区大小,未能及时写入子进程的输入流或读取输出流可能会导致子进程阻塞,甚至死锁。

所以你应该先阅读它:

InputStream is=process.getInputStream();
BufferedReader br= new BufferedReader(new InputStreamReader(is));

String line=new String();
while ((line=br.readLine())!=null) System.out.println (line);  //do something real here

如果您不想阅读您的 bat 输出(而且我看不到您这样做),您可以跳过所有这些并在其单独的窗口中运行您的命令:
cmd /c start \"my command\" c:/temp/startup.bat args

(注意关于工作目录的第二种形式,用于cmd /c startup.bat arguments摆脱“未找到”异常)

于 2012-08-21T20:23:28.670 回答