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

Posted

技术标签:

【中文标题】如何从我的 Java 应用程序运行批处理文件?【英文标题】:How do I run a batch file from my Java Application? 【发布时间】:2010-10-11 14:02:23 【问题描述】:

在我的 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 文件,但由于它不起作用,我决定通过批处理文件调用该脚本,但该方法尚未成功。

【问题讨论】:

【参考方案1】:

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

在 UNIX 上,脚本文件在文件开头有 shebang (#!) 以指定执行它的程序。 Windows 中的双击由 Windows Explorer 执行。 CreateProcess 对此一无所知。

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

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

【讨论】:

对我来说它说 Windows 找不到“build.bat”。那么我应该把这个文件放在哪里呢?或者我应该如何给出路径。有什么建议吗? 假设我有一个命令数组,然后迭代该数组以执行所有命令 for(i=0 to commands.length) Runtime.getRuntime().exec("cmd /c start建造.bat");然后对于每次迭代(对于每个命令)都会打开一个命令窗口,这很明显。如何避免我的意思是在一个窗口上执行所有命令。 我们有一些代码直接调用“gradlew.bat”而不在其前面放置“cmd /c”内容,并且该代码以某种方式工作。所以我猜Java或Windows在某些时候解决了部分问题。如果我们尝试执行“gradlew”,那会失败,所以很明显最后仍然需要“.bat”。 Win+R(运行时)可以直接执行批处理文件。【参考方案2】:

有时线程执行进程的时间比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 将停止,直到您调用的进程完成,然后再继续线程执行堆栈。

【讨论】:

【参考方案3】:
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() );

【讨论】:

注释此代码并告诉我们 InputStream 读取的原因和内容以及我关心的原因会很有用。此外,批处理文件的代码运行良好,但我无法让它引发错误异常。 我的代码中有一个像“is”这样令人困惑的变量名,这让我抓狂。【参考方案4】:

ProcessBuilder 是运行外部进程的 Java 5/6 方式。

【讨论】:

为什么 ProcessBuilder 是 Java 5/6 的方式? 复活旧帖子的有趣选择... ProcessBuilder 提供了更多控制,特别是能够轻松地将 stderr 重定向到 stdout。我也发现设置更直观,但这是个人偏好【参考方案5】:

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

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

应该这样做。

【讨论】:

这个问题已经得到了一个有效的解决方案。您应该只提供您知道有效的解决方案,并说明您认为您的解决方案可能更好的原因。【参考方案6】:

用于运行批处理脚本的可执行文件是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 可执行文件。如果这是您的问题,我可以进一步解释。

【讨论】:

谢谢。它仍然不起作用 - 那段代码甚至没有在我的应用程序中执行。我会尝试您提出的其他选项。再次感谢。 当我尝试第二种选择时,它给了我这个错误:线程“main”java.io.IOException中的异常:无法运行程序“scons”:CreateProcess error=2,系统找不到文件指定 不,我没有 Cygwin 终端。我使用 Windows 命令终端。这很奇怪 - 我不知道为什么它不起作用。这完全让我感到困惑。【参考方案7】:
Process p = Runtime.getRuntime().exec( 
  new String[]"cmd", "/C", "orgreg.bat",
  null, 
  new File("D://TEST//home//libs//"));

用 jdk1.5 和 jdk1.6 测试

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

【讨论】:

添加这个 ==> BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));字符串行 = reader.readLine(); while (line != null) System.out.println(line); line = reader.readLine(); 【参考方案8】:

我有同样的问题。但是有时 CMD 无法运行我的文件。 这就是为什么我在我的桌面上创建一个 temp.bat,接下来这个 temp.bat 将运行我的文件,接下来将删除这个临时文件。

我知道这是一个更大的代码,但是即使 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();

【讨论】:

【参考方案9】:

以下工作正常:

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

【讨论】:

/c 是什么意思?【参考方案10】:

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

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

【讨论】:

【参考方案11】:
import java.io.IOException;

public class TestBatch 

    public static void main(String[] args) 
        
            try 
                String[] command = "cmd.exe", "/C", "Start", "C:\\temp\\runtest.bat";
                Process p =  Runtime.getRuntime().exec(command);           
             catch (IOException ex) 
            
        

    


【讨论】:

请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助,质量更高,更有可能吸引投票。【参考方案12】:

要扩展 @Isha's anwser,您可以执行以下操作来获取已运行脚本的返回输出(事后不是实时):

try 
    Process process = Runtime.getRuntime().exec("cmd /c start D:\\temp\\a.bat");
    System.out.println(process.getText());
 catch(IOException e) 
    e.printStackTrace();

【讨论】:

以上是关于如何从我的 Java 应用程序运行批处理文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用批处理文件或curl从我的文本文件中删除' r n'?

如何制作批处理文件来运行java程序

从 C# 执行批处理文件

可以制作一个批处理程序,将文件夹文件从我的外部硬盘备份到 pc 硬盘,每当我添加或更改文件时?

我的批处理文件不断循环,但为啥?

从 Oracle 数据库调用批处理脚本/Java 代码