文系プログラマによるTIPSブログ

文系プログラマ脳の私が開発現場で学んだ事やプログラミングのTIPSをまとめています。

javaからwindowsのバッチファイル(*.bat)を実行する

これ、未だに重要あるのです〜


f:id:treeapps:20180424102046p:plain

今回はJavaから*.batを実行する方法についてまとめます。

説明が面倒なので、サンプルコードを。

サンプルコード

public int executeBat(String path) {
    String[] cmds = { "cmd.exe", "/c", "echo|" + path };
    try {
        return execCommand(cmds);
    } catch (Exception e) {
        e.printStacktrace();
    }
}

private int execCommand(String cmd) throws IOException, InterruptedException {
    return execCommand(new String[] { cmd });
}

private int execCommand(String[] cmds) throws IOException, InterruptedException {
    ProcessBuilder pb = new ProcessBuilder(cmds);
            // 標準エラー出力を標準出力にマージする
    pb.redirectErrorStream(true);
    Process process = pb.start();
    InputStream in = null;
    BufferedReader br = null;
    try {
        in = process.getInputStream();
        br = new BufferedReader(new InputStreamReader(in, "MS932"));
        String stdout = "";
        while ( (stdout = br.readLine()) != null) {
            // 不要なメッセージを表示しない
            if (StringUtils.isEmpty(stdout))
                continue;
            if (stdout.contains("echo off "))
                continue;
            if (stdout.contains("続行するには何かキーを押してください "))
                continue;
            System.out.println(stdout);
        }
        System.out.println();
        return process.waitFor();
    } finally {
        IOUtils.closeQuietly(br);
        IOUtils.closeQuietly(in);
    }
}

ポイントは3つほど。

「echo|」とは?

これは、コマンドプロンプトの PAUSE で停止しない為の措置です。

もしこれを書かないと、PAUSEから先に進まず、プログラムが実行したまま永遠に終了しません

具体的に何をしているかというと、空文字をパイプでバッチファイルに渡して、「何かキーを押下したことにしてPAUSEを突破する」という事をしています。

「new BufferedReader(new InputStreamReader(in, MS932"));」とは?

まず前提として、windowsのコマンドプロンプトはMS932(SHIFT_JISではない)です。従って、ストリームを取得する時点でMS932に変換しないと、確実に文字化けします。

「process.waitFor()」とは?

これは、バッチファイルの実行結果を表しています。返り値は基本的に「0=成功、1=失敗」です。

バッチの実行結果によって、エラー処理を入れたりします。

大まかにこんな感じでJavaからバッチファイルを実行することができます。