2009-04-16 1 views
0

コマンドラインからいくつかのコマンド( 'x'と言う)を実行すると、次のメッセージが表示されます。 "....続行するにはいずれかのキーを押します。したがって、ユーザーの入力がブロック解除されるのを待ちます。Javaで起動されたプロセスからどのようにブロックを解除できますか?

しかし、ときに私はJavaから同じコマンド(「X」)を実行します。

Process p = Runtime.getRuntime().exec(cmd, null, cmdDir); 
// here it blocks and cannot use outputstream to write somnething 
p.getOutputStream().write(..); 

コードブロックを...

私は、プロセスの出力ストリームに何かを書くしようとしましたが、どのようにすることができます私はコードがその行に到達することは決してないだろうか?

答えて

2

あなたはUnixではなくWindowsについて話していると思いますが(確かではありませんが)

もしそうなら、実際にコマンドラインプロセスがstdinのキーを押す(または入力する)のを待っているのではなく、古いDOS kbhit()の機能に相当することが考えられます。

AFAIK実際にキーを押さずにキーボードが押されたと考える機能はありません。

、この理論をテストし、その中にいくつかの空白行でテキストファイル「INPUT.TXT」を作成し、実行するには:

foo.exe < input.txt 

プログラムはstdinまたは何か他のもので待機しているかどうかを表示します。

0

ユーザーからの入力を期待してブロックされているため、プログラムが続行されません。

外部プロセスを別のスレッドで起動するか、プロセスpを共有するスレッドを使用してストリームに書き込むことができます。

2

サブプロセスの出力ストリームとエラーストリームを同時に読み取る必要があります。これらのストリームのバッファサイズは制限されています。バッファの1つがいっぱいになると、サブプロセスがブロックされます。私はそれがあなたの場合に起こると思います。

1

Javaで外部アプリケーションを実行することが推奨されているのは、ProcessBuilderを使用していると思います。コードは次のようになります

//Launch the program 
ArrayList<String> command = new ArrayList<String>(); 
command.add(_program); 
command.add(param1); 
... 
command.add(param1); 

ProcessBuilder builder = new ProcessBuilder(command); 
//Redirect error stream to output stream 
builder.redirectErrorStream(true); 

Process process = null; 
BufferedReader br = null; 
try{ 
    process = builder.start(); 

    InputStream is = process.getInputStream(); 
    br = new BufferedReader(new InputStreamReader(is)); 
    String line; 

    while ((line = br.readLine()) != null) { 
     log.add(line); 
    } 
}catch (IOException e){ 
    e.printStackTrace(); 
}finally{ 
    try{ 
     br.close(); 
    }catch (IOException e){ 
     e.printStackTrace(); 
    } 
} 

プロセスオブジェクトには、プログラムとやりとりするために使用できるget [Input/Output/Error] Streamがあります。

0

私はコマンドライン実行の回答をthis stackoverflow questionに書いています。

返信する必要があるため、あなたの方がやや難解です。

StreamGobbler outputGobbler = new StreamGobbler(
            proc.getInputStream(), "OUTPUT", 
            proc.getOutputStream()); 

、それは与えられた入力ストリーム上のパターンと返事を一致させる:それは私に必要な入力ストリームゴブラーに返信チャネルのようなものを与えるかもしれないあなたの場合

while ((line = br.readLine()) != null) { 
    System.out.println(type + ">" + line); 
    if (line.contains(PRESS_KEY_CONTINUE) { 
     ostream.write("y".getBytes("US-ASCII")); 
     System.out.println("< y"); 
    } 
} 

希望します。

0

だから、これはオリオン座ゼータ星の提案からインスピレーションを得た、この問題への私の回避策です: を実行し、このようなコマンド:

Process p = Runtime.getRuntime().exec(cmd + " < c:\\someTextFile.txt", null, cmdDir); 
... 
int errCode = p.waitFor(); 
... 

「someTextFile.txt」は、プログラムで、その後削除された一時的なディレクトリに作成することができます。

0

は、いくつかの入力をシミュレートするPrintWriterを使用します。

 Process p = Runtime.getRuntime().exec(cmd, null, cmdDir); 
     //consume the proces's input stream 
     ........ 
     // deblock 
     OutputStream outputStream = p.getOutputStream(); 
     PrintWriter pw = new PrintWriter(outputStream); 
     pw.write("ok"); 
     pw.flush(); 
     int errCode = p.waitFor(); 
0

私は同じ問題を抱えていたと私は解決策を見つけました。それは最もエレガントではありませんが、機能します。あなたがプロセスを実行するとき、あなたはプロセス 2からInputStreamを取得 - -

1は1 3があったなら、あなたは、プロンプトに示されているメッセージを受信するループを作る - あなたはあなたから得たことを見ると "プロンプト "を押して"続行するキーを押す "、または何でも、あなたはプロセスを終了する

  // Creates the runtime and calls the command 
     Process proc = Runtime.getRuntime().exec(Destino); 

     // Get the proccess inputStream 
     InputStream ips = proc.getInputStream(); 
     String output = ""; 

     int c = 0; 

     // Read the output of the pro 
     while ((c = ips.read()) != -1 
       && !output.contains("Press any key to continue")) { 
      output = output + (char)c; 
     } 

     // Destroy the proccess when you get the desired message 
     proc.destroy(); 
関連する問題