2017-07-12 18 views
0

JavaFX GUIからアプリケーションを起動できません。私はProcessBuilderを使用しています。プロセスを作成しますが、Javaプログラムを閉じるまで、アプリケーションは起動しません。それは特定のプログラムが引数や私のコードに間違っているのを待っているからですか?Java内の外部アプリケーションの起動

@FXML 
private void runWorldpac() { 
    try { 
     ProcessBuilder process = new ProcessBuilder("C:\\speedDIAL\\speedDIAL.exe"); 
     Process p = process.start(); 

    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

} 

この外部プログラムを閉じるまで、外部アプリケーションは起動しますが、元のアプリケーションとのやり取りは許可されません。新しいスレッド、同じ結果を実行しようとしました。

try { 
      ProcessBuilder process = new ProcessBuilder("C:\\speedDIAL\\speedDIAL.exe"); 
      Map<String, String> environ = process.environment(); 
      Process p = process.start(); 
      InputStream is = p.getInputStream(); 
      InputStreamReader isr = new InputStreamReader(is); 
      BufferedReader br = new BufferedReader(isr); 
      String line; 
      while ((line = br.readLine()) != null) { 
       //System.out.println(line); 
      } 
      System.out.println("Program terminated!"); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
+0

ここで、プロセスで生成されるストリームを処理していますか?それは私がここでやる最初のことの一つであり、自分のプロセスが独自のスレッドで実行されることを保証するものです。 –

+0

この外部アプリケーションはデータをアプリケーションに送り返すことは想定されていませんが、ストリームを処理する必要はありますか?だから私は別のスレッドで実行するように指定する必要がありますか?私はそれがすでにそれをやっていると思ったので、私は私のアプリケーションを閉じると、外部アプリケーションは実行中(実際に実行を開始する)のままです。申し訳ありませんが、私は比較的新しいです。ありがとう。 –

+0

はい、ストリームを絶対に処理する必要があります。そうしないと、アプリケーションがバッファメモリを使い果たし、デッドロックが発生する可能性があります。 [Runtime.exec()が実行されない場合](http://www.javaworld.com/article/2071275/core-java/when-runtime-exec---won-t.html)をお読みください。この記事には日付情報が含まれています(ProcessBuilderを使用していない)が、そこに含まれる情報の多くはポイント上のものです。 –

答えて

2

その記事、良い情報を読む: ここに新しいコードです。ここにも良い例があります。それは新しいスレッドで実行されていますが、私のプログラムは外部アプリケーションが終了する前に終了するのを待っていますが、通常は必要ですが、この場合はどうすれば無効にできますか?

新しいスレッドで終了値が生成されるのを待ちます。次のようなものがあります:

try { 
    ProcessBuilder pBuilder = new ProcessBuilder("C:\\speedDIAL\\speedDIAL.exe"); 

    // don't forget to handle the error stream, and so 
    // either combine error stream with input stream, as shown here 
    // or gobble it separately 
    pBuilder.redirectErrorStream(true); 
    final Process process = pBuilder.start(); 
    final InputStream is = process.getInputStream(); 

    // in case you need to send information back to the process 
    // get its output stream. Don't forget to close when through with it 
    final OutputStream os = process.getOutputStream(); 

    // thread to handle or gobble text sent from input stream 
    new Thread(() -> { 
     // try with resources 
     try (BufferedReader reader = new BufferedReader(new InputStreamReader(is));) { 
      String line = null; 
      while ((line = reader.readLine()) != null) { 
       // TODO: handle line 
      } 
     } catch (IOException ex) { 
      ex.printStackTrace(); 
     } 
    }).start(); 

    // thread to get exit value from process without blocking 
    Thread waitForThread = new Thread(() -> { 
     try { 
      int exitValue = process.waitFor(); 
      // TODO: handle exit value here 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    }); 
    waitForThread.start(); 

    // if you want to join after a certain time: 
    long timeOut = 4000; 
    waitForThread.join(timeOut); 
} catch (IOException | InterruptedException e) { 
    e.printStackTrace(); 
} 
+0

それは完璧に動作します。コメントはすべてを説明するのに非常に役立ちますので、私のプログラムが正しいのを待たないようにするには、終了値を扱う別のスレッドを作成する必要がありますか? –

+0

@Karodarmoyan:yes –

関連する問題