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ファイルがありましたが、それが機能しなかったので、バッチファイルを介してスクリプトを呼び出すことにしましたが、その方法はまだ成功していません。

回答:


172

バッチファイルは実行可能ファイルではありません。それらを実行するには、アプリケーション(つまり、cmd)が必要です。

UNIXでは、スクリプトファイルのファイルの先頭にシバン(#!)があり、スクリプトを実行するプログラムを指定します。Windowsでのダブルクリックは、Windowsエクスプローラによって実行されます。 CreateProcessそれについては何も知りません。

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

注:start \"\"コマンドを使用すると、別のコマンドウィンドウが空白のタイトルで開かれ、バッチファイルからの出力がそこに表示されます。また、 `cmd / c build.bat"だけでも動作するはずです。この場合、必要に応じて、Javaのサブプロセスから出力を読み取ることができます。


私にとって、Windowsは「build.bat」を見つけることができないと言っています。それで、このファイルをどこに置くべきですか?または、どのようにパスを指定する必要がありますか。助言がありますか?
nanospeck

1
コマンドの配列があり、その配列を反復してすべてのコマンドを実行するとします(i = 0 to commands.length){Runtime.getRuntime()。exec( "cmd / c start buil.bat"); 次に、すべての反復(すべてのコマンド)に対して、コマンドウィンドウが開かれます。これを回避するには、1つのウィンドウですべてのコマンドを実行する必要があります。
viveksinghggits

1
"gradlew.bat"を直接呼び出すコードがあり、その前に "cmd / c"を配置せずに、そのコードが何らかの方法で機能しています。したがって、JavaまたはWindowsのいずれかで問題の一部が修正されたと思います。「gradlew」を実行しようとすると失敗しますが、明らかに最後に「.bat」がまだ必要です。
Trejkaz 2017

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が読み取っている理由と内容、そして気にした理由を教えてください。また、バッチファイルのコードは問題なく実行されていますが、エラー例外を発生させることができません。
Baruch Atta 2017

2
コードで "is"のような紛らわしい変数名を使用すると、私は気が遠くなるでしょう。
ジョンフィッシャー

14

それがあなたが話しているなら、Javaを使用してバッチファイルを実行するには...

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

これでうまくいくはずです。


10
質問はすでに実用的な解決策で答えられました。機能していることがわかっているソリューションのみを提供し、ソリューションが優れていると考える理由を説明する必要があります。
スマティ

12

ProcessBuilderは、外部プロセスを実行するJava 5/6の方法です。


2
なぜProcessBuilderはJava 5/6に移行する方法なのですか?
Dan Polites、2010年

2
古い投稿を復活させる興味深い選択肢... ProcessBuilderは、より詳細な制御、特にstderrをstdoutに簡単にリダイレクトする機能を提供します。また、セットアップはより直感的ですが、それは個人的な
好みです

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を見つけられないことです。これがあなたの問題であることが判明した場合は、さらに説明できます。


ありがとうございました。それでも動作しません-そのコードは私のアプリでも実行されません。あなたが提示した他のオプションを試します。再度、感謝します。
アマラ

2番目の代替方法を試すと、次のエラーが発生します:スレッド "main"の例外java.io.IOException:プログラム "scons"を実行できません:CreateProcess error = 2、システムが指定されたファイルを見つけられません
Amara

いいえ、Cygwinターミナルを持っていません。Windowsのコマンドターミナルを使用しています。それは奇妙です-それがうまくいかない理由がわかりません。それは私を完全に困惑させます。
アマラ

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リーダー= new BufferedReader(new InputStreamReader(p.getInputStream())); 文字列line = reader.readLine(); while(line!= null){System.out.println(line); line = reader.readLine(); }
Suren

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 2018

0

このコードは、パスC:/ folders / folderにある2つのcommands.batを実行します。

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

0

@Ishaのアンサーを拡張するには、次のようにして、実行されたスクリプトの返された出力(rea-ltimeではなくpost-facto)を取得します。

try {
    Process process = Runtime.getRuntime().exec("cmd /c start D:\\temp\\a.bat");
    System.out.println(process.getText());
} catch(IOException e) {
    e.printStackTrace();
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.