web-dev-qa-db-ja.com

Javaでプロセスを開始しますか?

Javaでプロセスを開始する方法はありますか? .Netでは、これはたとえば次のように行われます。

System.Diagnostics.Process.Start("processname");

Javaに同等のものがあるので、ユーザーにアプリケーションを見つけさせると、どのOSでも動作しますか?

31
jmasterx

http://www.rgagnon.com/javadetails/Java-0014.html

import Java.io.BufferedReader;
import Java.io.InputStreamReader;
import Java.nio.file.Paths;

public class CmdExec {

public static void main(String args[]) {
    try {
        // enter code here

        Process p = Runtime.getRuntime().exec(
            Paths.get(System.getenv("windir"), "system32", "tree.com /A").toString()
        );

        // enter code here

        try(BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
            String line;

            while ((line = input.readLine()) != null) {
                System.out.println(line);
            }
        }

    } catch (Exception err) {
        err.printStackTrace();
    }
  }
}

システムプロパティまたは同様のアプローチを使用して、ローカルパスを取得できます。

http://download.Oracle.com/javase/tutorial/essential/environment/sysprop.html

31
James P.

Runtime.exec() および Process クラスを参照してください。最も単純な形式では:

_Process myProcess = Runtime.getRuntime().exec(command);
...
_

プロセスの出力(例:myProcess.getInputStream())も読み取る必要があります。そうしないと、プロセスが一部のシステムでハングすることに注意してください。これは初めて非常に混乱する可能性があるため、これらのAPIの紹介に含める必要があります。例については、James P.の応答を参照してください。

また、新しい ProcessBuilder クラスを調べると、環境変数の変更やサブプロセスの呼び出しが簡単になります。

_Process myProcess = new ProcessBuilder(command, arg).start();
...
_
22

Javaクラスライブラリは _Java.lang.Process_ クラスを使用して外部プロセスを表します。プロセスは _Java.lang.ProcessBuilder_ を使用して生成できます。 :

_Process process = new ProcessBuilder("processname").start();
_

または _Java.lang.Runtime_ クラスのオーバーロードされたexecメソッドによって公開された古いインターフェイス:

_Process process = Runtime.getRuntime().exec("processname");
_

これらは両方ともスニペットをコーディングし、通常は非同期で実行され、結果の Process オブジェクトを通じて対話できる新しいプロセスを生成します。プロセスが終了したことを確認する(または終了するまで待つ)必要がある場合は、 process.exitValue() によって返される終了値(終了コード)を確認することを忘れないでください。 process.waitFor() は、プロセスが異常終了した場合に例外がスローされないため、期待どおりです(ほとんどのプログラムでは0)。

Processクラスのドキュメント (強調を追加)で説明されているように、プロセスのI/Oを正しく処理するために追加コードが必要になることがよくあります。

デフォルトでは、作成されたサブプロセスには独自の端末またはコンソールがありません。すべての標準I/O(つまり、stdin、stdout、stderr)操作は、親プロセスにリダイレクトされ、getOutputStream()、getInputStream()、およびgetErrorStream()メソッドを使用して取得したストリームを介してアクセスできます。親プロセスはこれらのストリームを使用して、サブプロセスに入力を供給し、サブプロセスから出力を取得します。一部のネイティブプラットフォームは、標準の入力および出力ストリームに限られたバッファサイズしか提供しないため、サブプロセスの入力ストリームの書き込みまたは出力ストリームの読み取りに失敗すると、サブプロセスがブロックされたり、デッドロックが発生したりすることがあります

I/Oが正しく処理され、終了値が成功を示すことを確認する1つの方法は、stdoutとstderrのキャプチャの複雑さを扱う jproc のようなライブラリを使用することです。外部プロセスを実行するためのシンプルな同期インターフェースを提供します:

_ProcResult result = new ProcBuilder("processname").run();
_

jprocは、Maven Centralから入手できます。

_<dependency>
      <groupId>org.buildobjects</groupId>
      <artifactId>jproc</artifactId>
      <version>2.2.0</version>
</dependency>
_
15
Felix Leipold