Java ProcessBuilder:找到.cmd nad .exe但不是.bat

时间:2016-09-09 00:03:49

标签: java external

正如标题所说,我使用的是基本的ProcessBuilder:

ProcessBuilder pb = new ProcessBuilder(new String[] {this.getExecutable(), "--version"});
             pb.directory(pomDir);
             pb.redirectOutput(appendTo(log));
             Process p = pb.start();
             p.waitFor();

如果getExecutable()是路径上的.exe(如Python.exe)或.cmd(如npm.cmd),则可行。

但是,如果它是.bat(如mvn.bat),则不会。

以下是相关路径条目:

c:\Python27;
c:\Users\Matt\Tools\apache-maven-3.3.9\bin;
c:\Users\Matt\Tools\node;

python的输出--version:

Python 2.7.10

输出mvn --version:

Exception in thread "main" java.lang.RuntimeException: Error running mvn init
        at tech.project.trait.act(act.java:81)
        at tech.project.admin.action.LastDependendantInvoker.invoke(LastDependendantInvoker.java:23)
        at tech.project.admin.command.NewAppCommand.execute(NewAppCommand.java:71)
        at tech.project.admin.command.init.InitCommand.execute(InitCommand.java:33)
        at tech.project.admin.CLI.main(CLI.java:83)
Caused by: java.io.IOException: Cannot run program "mvn.bat" (in directory "c:\Users\Matt\Documents\Projects\foo"): CreateProcess error=2, The system cannot find the file specified
        at java.lang.ProcessBuilder.start(Unknown Source)
        at tech.project.trait.act(act.java:75)
        ... 4 more
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
        at java.lang.ProcessImpl.create(Native Method)
        at java.lang.ProcessImpl.<init>(Unknown Source)
        at java.lang.ProcessImpl.start(Unknown Source)
        ... 6 more

如果我尝试将其包裹在cmd中,我得到:

cmd //C mvn --version
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.

从命令行,mvn --version返回:

mvn --version
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-10T10:41:47-06:00)
Maven home: c:\Users\Matt\Tools\apache-maven-3.3.9
Java version: 1.8.0_73, vendor: Oracle Corporation
Java home: c:\Program Files\Java\jdk1.8.0_73\jre
Default locale: en_US, platform encoding: Cp1252
OS name: "windows 10", version: "10.0", arch: "amd64", family: "dos"

思想?

根据@ Adroidan的评论,我试过:

"cmd.exe", "//C",  "\""+this.getExecutable()+" --version\""

但是这似乎产生了一个新的cmd shell,并打印了cmd.exe版本:

Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.

从命令行,等效工作正常:

$ cmd.exe //C "mvn --version"
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-10T10:41:47-06:00)
Maven home: C:\Users\Matt\Tools\apache-maven-3.3.9
Java version: 1.8.0_73, vendor: Oracle Corporation
Java home: C:\Program Files\Java\jdk1.8.0_73\jre
Default locale: en_US, platform encoding: Cp1252
OS name: "windows 10", version: "10.0", arch: "amd64", family: "dos"

2 个答案:

答案 0 :(得分:4)

以下是基础知识:

  • 对于bat文件,可执行文件应为"cmd.exe"
  • 参数是bat及其参数作为单个字符串,例如"mvn --version"
  • 添加"/C"以便cmd shell无法继续运行

因此您的代码应如下所示:

new ProcessBuilder().command("cmd.exe", "/C", "mvn --version")

(尽管您可能需要完全限定mvn

的路径

这是一个完整的最小工作示例:

使用以下内容创建文件c:\tools\test.bat

@echo off
echo I was passed: %1

然后,运行这个:

Process p = new ProcessBuilder().command("cmd.exe", "/C", "/tools/test.bat foo").start();
p.waitFor();
System.out.println(new Scanner(p.getInputStream()).useDelimiter("\\A").next());

产生这个:

I was passed: foo

答案 1 :(得分:2)

.bat不是可执行文件,因为它没有编译。

为了获得更多帮助,可能需要有关您正在尝试做什么的更多信息。您可能需要将命令包装在cmd.exe中,这是实际可以运行批处理文件的shell。