0

共有場所にexeプログラムを配置しました。起動中は引数を取りません。コマンドウィンドウで起動すると、それを使用して実行できるコマンドのリストを含むヘルプメニューが表示され>、入力コマンドを期待して終了します。TRIGGERそのリストから呼び出された特定のコマンドを実行する必要があります。これまでのところ、これは私が行ったことですが、完全に失敗します。プロセスからの出力を表示することもtrigger、ストリームから入力コマンドを受け取ることもありません。

public void execute(){

    String cmd = "\\\\sharedLocation\\server\\adm.exe";
    p = Runtime.getRuntime().exec(cmd);

    InputStream in = p.getInputStream();
    OutputStream out = p.getOutputStream();

    BufferedReader br= new BufferedReader(new InputStreamReader(in));
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));

    bw.write("TRIGGER");            
    bw.flush();

    String output = "";
    while (!output.endsWith(">")) {     
        System.out.println("in loop");
        output = output + br.readLine(); 
    }

    System.out.println("Out"+output);


    out.close();            
    p.waitFor();
}

編集:adm.exeはこのプログラムによって起動されますが、adm.exeはブロッキングプロセスのようです。「ループ内」ステートメントの印刷に失敗します。ただし、Windowsタスクマネージャーを開いてadm.exeプロセスツリーを強制終了すると、コンソールに表示されます

in loopnull
in loopnullnull
in loopnullnullnull
in loopnullnullnullnull
in loopnullnullnullnullnull
in loopnullnullnullnullnullnull
in loopnullnullnullnullnullnullnull
in loopnullnullnullnullnullnullnullnull
in loopnullnullnullnullnullnullnullnullnull
in loopnullnullnullnullnullnullnullnullnullnull
in loopnullnullnullnullnullnullnullnullnullnullnull
in loopnullnullnullnullnullnullnullnullnullnullnullnull
in loopnullnullnullnullnullnullnullnullnullnullnullnullnull
in loopnullnullnullnullnullnullnullnullnullnullnullnullnullnull
in loopnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
in loopnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
in loopnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
in loopnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
Outnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
4

2 に答える 2

1

わかりませんが...

タイミング

while出力とそのファイナライズを待つときにexecuteメソッドがブロックされることを理解しています。TRIGGERを送るまで来ません。

私はしようとします

  1. 前にTRIGGERを送信します(データが失われることはなく、バッファリングされます)
  2. メソッドの最後に、p.waitFor()pが終了するまで終了しないように使用します(とにかく、しばらくの間は終了します)。

編集

adm.exeにはUTF-16で記述されたTRIGGERが必要ですか?を使用する場合は、それを送信するためgetBytes()です。別のエンコーディング(UTF-8やASCIIなど)が必要な場合はgetBytes("UTF-8")、例を試してみてください。

サンプル

私は次のようなことをする必要があります:

public void execute() {

String cmd = "\\\\sharedLocation\\server\\adm.exe";
Process p = Runtime.getRuntime().exec(cmd);     

// send TRIGGER before everything (I can't consume the response if I don't ask for it first)
OutputStream out = p.getOutputStream();
out.write("TRIGGER".getBytes());
out.flush(); // flush to ensure it's sent, but don't close...

InputStream in = p.getInputStream();

String output = "";
int c = 0;
while (!output.endsWith(">")){
    c = in.read(); // you've eaten this when modified your code
    output+= (char)c; // I should change the way bytes convert to char, but that's another story
}

System.out.println(output);


// optional: if I want to wait for p to finish
p.waitFor();
}
于 2012-07-23T10:18:20.923 に答える
1

いくつかの一般的なコメント:

  1. 使用せずProcessProcessBuilder代わりに使用してください。また、外部プロセスを開始するよりも複雑なことをしたい場合は、CommonsExecを使用してください。

  2. TRIGGERを押さずにコマンドラインで入力するとどうなりReturnますか?何も起こらない場合は、Javaからのreturnキーも押してくださいoutPrintStreampw.println("TRIGGER")

  3. 出力が得られないので、コマンドプロンプトから開始されていないことにコマンドが気づき、動作が異なる可能性がありますか?その場合は、で実行してくださいcmd /c \\\\sharedLocation\\server\\adm.exe

  4. 特殊文字の問題を回避するために、常にリスト/配列を使用してコマンド引数を指定してください

于 2012-07-23T11:56:17.403 に答える