web-dev-qa-db-ja.com

Java経由でcmdコマンドを実行する方法

Java経由でコマンドライン引数を実行しようとしています。例えば:

// Execute command
String command = "cmd /c start cmd.exe";
Process child = Runtime.getRuntime().exec(command);

// Get output stream to write from it
OutputStream out = child.getOutputStream();

out.write("cd C:/ /r/n".getBytes());
out.flush();
out.write("dir /r/n".getBytes());
out.close();

上記はコマンドラインを開きますが、cdまたはdirを実行しません。何か案は? Windows XP、JRE6を実行しています。

(質問をより具体的に修正しました。次の回答は役に立ちましたが、質問には答えません。)

41
joe

投稿したコードは、それぞれ独自のコマンドで3つの異なるプロセスを開始します。コマンドプロンプトを開いてからコマンドを実行するには、次のことを試してください(自分で試してはいけません)。

try {
    // Execute command
    String command = "cmd /c start cmd.exe";
    Process child = Runtime.getRuntime().exec(command);

    // Get output stream to write from it
    OutputStream out = child.getOutputStream();

    out.write("cd C:/ /r/n".getBytes());
    out.flush();
    out.write("dir /r/n".getBytes());
    out.close();
} catch (IOException e) {
}
3
Peter Knego

Forums.Oracle.comでこれを見つけました

Windowsで複数のコマンドを実行するプロセスを再利用できます。 http://kr.forums.Oracle.com/forums/thread.jspa?messageID=9250051

次のようなものが必要です

   String[] command =
    {
        "cmd",
    };
    Process p = Runtime.getRuntime().exec(command);
    new Thread(new SyncPipe(p.getErrorStream(), System.err)).start();
    new Thread(new SyncPipe(p.getInputStream(), System.out)).start();
    PrintWriter stdin = new PrintWriter(p.getOutputStream());
    stdin.println("dir c:\\ /A /Q");
    // write any other commands you want here
    stdin.close();
    int returnCode = p.waitFor();
    System.out.println("Return code = " + returnCode);

SyncPipeクラス:

class SyncPipe implements Runnable
{
public SyncPipe(InputStream istrm, OutputStream ostrm) {
      istrm_ = istrm;
      ostrm_ = ostrm;
  }
  public void run() {
      try
      {
          final byte[] buffer = new byte[1024];
          for (int length = 0; (length = istrm_.read(buffer)) != -1; )
          {
              ostrm_.write(buffer, 0, length);
          }
      }
      catch (Exception e)
      {
          e.printStackTrace();
      }
  }
  private final OutputStream ostrm_;
  private final InputStream istrm_;
}
63
Pepe

Cmdシェルで複数のコマンドを実行する場合、次のような単一のコマンドを作成できます。

  rt.exec("cmd /c start cmd.exe /K \"cd c:/ && dir\"");

このページ 詳細を説明します。

15

execを実行するたびに、独自の環境を持つ新しいプロセスが生成されます。したがって、2番目の呼び出しは、最初の呼び出しとはまったく関係ありません。 its own作業ディレクトリを変更して終了します(つまり、実質的に何もしません)。

リクエストを作成する場合は、execへの1回の呼び出しでこれを行う必要があります。 Bashでは、セミコロンで区切られた複数のコマンドを1行で指定できます。 Windows CMDは同じものを許可する場合があり、そうでない場合は常にバッチスクリプトがあります。

Piotrが言うように 、この例が実際に達成しようとしているものであれば、次のようにして同じことをより効率的、効果的、プラットフォーム安全に実行できます。

String[] filenames = new Java.io.File("C:/").list();
3
Andrzej Doyle

これを試してください link

コマンドを実行するディレクトリを変更するために「cd」を使用しないでください。実行する実行可能ファイルの完全なパスが必要です。

また、ファイル/ディレクトリクラスを使用すると、ディレクトリの内容をリストするのが簡単になります。

2
Piotr

Exec呼び出しのそれぞれがプロセスを作成します。 2番目と3番目の呼び出しは、最初の呼び出しで作成したのと同じシェルプロセスでは実行されません。すべてのコマンドをbatスクリプトに入れて、1回の呼び出しで実行してみてください:rt.exec("cmd myfile.bat");または同様のもの

1

プロセスから出力ストリームへの書き込みは間違った方向です。その場合の「アウト」とは、プロセスからあなたまでを意味します。プロセスの入力ストリームへの取得/書き込みと出力ストリームからの読み取りを試して結果を確認してください。

0
Kelly S. French

これは、すべてのruntime.exec(..)Processクラスによって他のコマンドを呼び出す代わりに実行後に使用されるRuntimeクラスを返すためです

Process doc を見ると、使用できることがわかります。

  • getInputStream()
  • getOutputStream()

連続したコマンドを送信し、出力を取得することで作業する必要があります。

0
Jack

私も同じ問題に直面しており、ここの一部の人々は解決策が彼らのために機能していないとコメントしたので、ここに実用的な解決策が見つかった投稿へのリンクがあります。

https://stackoverflow.com/a/24406721/375159

Cygwinターミナルを使用するためのベストアンサーの「更新」も参照してください。

0
singe3