如何从Java应用程序运行批处理文件?


107

在我的Java应用程序中,我想运行一个名为“ scons -Q implicit-deps-changed build\file_load_type export\file_load_type” 的批处理文件

看来我什至无法执行我的批处理文件。我没主意了。

这就是我在Java中所拥有的:

Runtime.
   getRuntime().
   exec("build.bat", null, new File("."));

以前,我有一个要运行的Python Sconscript文件,但由于该文件不起作用,我决定通过批处理文件调用该脚本,但该方法迄今尚未成功。

Answers:


172

批处理文件不是可执行文件。他们需要一个应用程序来运行它们(即cmd)。

在UNIX上,脚本文件的文件开头有shebang(#!),用于指定执行该脚本的程序。在Windows中双击是由Windows资源管理器执行的。 CreateProcess对此一无所知。

Runtime.
   getRuntime().
   exec("cmd /c start \"\" build.bat");

注意:使用该start \"\"命令,将打开一个单独的命令窗口,标题标题为空白,并且批处理文件的所有输出都将显示在该窗口中。它也应该只与“ cmd / c build.bat”一起使用,在这种情况下,如果需要,可以从Java子进程中读取输出。


对我来说,它说Windows无法找到“ build.bat”。所以我应该把这个文件放在哪里?还是我应该给出路径。有什么建议?
nanospeck

1
可以说我有一个命令数组,然后迭代该数组以执行所有命令(i = 0到commands.length){Runtime.getRuntime()。exec(“ cmd / c start buil.bat”); 然后,对于每次迭代(对于每个命令),都会打开一个命令窗口,这是显而易见的。如何避免那意味着我要在一个窗口上执行所有命令。
viveksinghggits

1
我们有一些代码直接调用“ gradlew.bat”,而没有在其前面加上“ cmd / c”东西,并且该代码以某种方式起作用。因此,我猜想Java或Windows在某个时候解决了部分问题。如果我们尝试执行“ gradlew”,那将会失败,因此很明显,最后仍然需要“ .bat”。
Trejkaz

Win+R(运行时)可以直接执行批处理文件。
Alex78191

21

有时,线程执行过程的时间要比JVM线程等待过程的时间长,这通常发生在您要调用的过程需要一些时间来处理时,请使用waitFor()命令,如下所示:

try{    
    Process p = Runtime.getRuntime().exec("file location here, don't forget using / instead of \\ to make it interoperable");
    p.waitFor();

}catch( IOException ex ){
    //Validate the case the file can't be accesed (not enought permissions)

}catch( InterruptedException ex ){
    //Validate the case the process is being stopped by some external situation     

}

这样,JVM将停止,直到您要调用的进程完成后才继续执行线程执行堆栈。


20
Runtime runtime = Runtime.getRuntime();
try {
    Process p1 = runtime.exec("cmd /c start D:\\temp\\a.bat");
    InputStream is = p1.getInputStream();
    int i = 0;
    while( (i = is.read() ) != -1) {
        System.out.print((char)i);
    }
} catch(IOException ioException) {
    System.out.println(ioException.getMessage() );
}

2
注释该代码并告诉我们InputStream为何以及正在阅读什么,以及我为什么在乎,这将很有用。另外,批处理文件的代码运行良好,但是我无法获取它以引发错误Exception。
Baruch Atta

2
在代码中使用“ is”这样令人困惑的变量名真让我发疯。
约翰·费舍尔

14

如果您正在谈论使用Java运行批处理文件...

String path="cmd /c start d:\\sample\\sample.bat";
Runtime rn=Runtime.getRuntime();
Process pr=rn.exec(path);`

这应该做。


10
该问题已经通过有效的解决方案得到了解答。您应该只提供已知有效的解决方案,并说明为什么您认为您的解决方案可能会更好。
Smamatti 2012年

12

ProcessBuilder是运行外部流程的Java 5/6方法。


2
为什么在Java 5/6中使用ProcessBuilder?
Dan Polites

2
复活旧帖子的有趣选择。ProcessBuilder提供了更多控制权,尤其是可以轻松地将stderr重定向到stdout的功能。我还发现设置更直观,但这是个人喜好
basszero 2010年

10

用于运行批处理脚本的可执行文件是cmd.exe使用/c标志来指定要运行的批处理文件的名称的可执行文件:

Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", "build.bat"});

从理论上讲,尽管我尚未对此进行测试,但您也应该能够以这种方式运行Scons:

Runtime.getRuntime().exec(new String[]{"scons", "-Q", "implicit-deps-changed", "build\file_load_type", "export\file_load_type"});

编辑:阿马拉,你说这是行不通的。您列出的错误是从Windows机器上的Cygwin终端运行Java时获得的错误。这是你在做什么吗?问题在于Windows和Cygwin具有不同的路径,因此Windows版本的Java在Cygwin路径上找不到scons可执行文件。如果这是您的问题,我可以进一步解释。


谢谢。它仍然不起作用-这段代码甚至都没有在我的应用程序中执行。我将尝试您提出的其他选项。再次感谢。
阿马拉2009年

当我尝试第二种替代方法时,它给了我这个错误:线程“ main”中的异常java.io.IOException:无法运行程序“ scons”:CreateProcess error = 2,系统找不到指定的文件
Amara

不,我没有Cygwin终端机。我使用Windows Command终端。很奇怪-我不知道为什么它不起作用。这完全让我感到困惑。
阿马拉2009年

3
Process p = Runtime.getRuntime().exec( 
  new String[]{"cmd", "/C", "orgreg.bat"},
  null, 
  new File("D://TEST//home//libs//"));

用jdk1.5和jdk1.6测试

这对我来说很好,希望对其他人也有帮助。为了得到这个,我已经挣扎了更多的日子。:(


1
添加此==> BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); 字符串行= reader.readLine(); while(line!= null){System.out.println(line); 行= reader.readLine(); }
Suren 2013年

2

我遇到过同样的问题。但是,有时CMD无法运行我的文件。这就是为什么我在桌面上创建一个temp.bat的原因,下一个该temp.bat将运行我的文件,下一个该temp文件将被删除。

我知道这是一个更大的代码,但是即使Runtime.getRuntime()。exec()失败,它也可以100%地为我工作。

// creating a string for the Userprofile (either C:\Admin or whatever)
String userprofile = System.getenv("USERPROFILE");

BufferedWriter writer = null;
        try {
            //create a temporary file
            File logFile = new File(userprofile+"\\Desktop\\temp.bat");   
            writer = new BufferedWriter(new FileWriter(logFile));

            // Here comes the lines for the batch file!
            // First line is @echo off
            // Next line is the directory of our file
            // Then we open our file in that directory and exit the cmd
            // To seperate each line, please use \r\n
            writer.write("cd %ProgramFiles(x86)%\\SOME_FOLDER \r\nstart xyz.bat \r\nexit");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                // Close the writer regardless of what happens...
                writer.close();
            } catch (Exception e) {
            }

        }

        // running our temp.bat file
        Runtime rt = Runtime.getRuntime();
        try {

            Process pr = rt.exec("cmd /c start \"\" \""+userprofile+"\\Desktop\\temp.bat" );
            pr.getOutputStream().close();
        } catch (IOException ex) {
            Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);

        }
        // deleting our temp file
        File databl = new File(userprofile+"\\Desktop\\temp.bat");
        databl.delete();

1

以下工作正常:

String path="cmd /c start d:\\sample\\sample.bat";
Runtime rn=Runtime.getRuntime();
Process pr=rn.exec(path);

/ c是什么意思?
Amal lal TL

0

此代码将执行路径C:/ folders / folder中存在的两个command.bat。

Runtime.getRuntime().exec("cd C:/folders/folder & call commands.bat");

0

要扩展@Isha的anwser,您可以执行以下操作以获取运行的脚本的返回输出(事实上,不在rea-ltime中):

try {
    Process process = Runtime.getRuntime().exec("cmd /c start D:\\temp\\a.bat");
    System.out.println(process.getText());
} catch(IOException e) {
    e.printStackTrace();
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.