◆PROCESSING 逆引きリファレンス
カテゴリー:制御系
外部プログラムを起動するには
【概要】
プログラムから、他の実行モジュール(外部プログラム)を起動したい事は無いでしょうか?
例えばPROCESSINGからブラウザーやメモ帳を呼び出すようなケースが考えられます。
PROCESSINGには、このようなときに使えるlaunch()命令とexec()命令があります。
またPROCESSINGはJavaをベースにした言語ですので、JavaのProcessBuilderクラスを利用する事も可能です。
【詳細】
launch()命令を使う
外部プログラムを呼び出すProcess p = launch( String args[] );
p:生成されたプロセス情報
args:起動コマンドとパラメータの配列
戻り値には、JavaのProcessクラスが戻されます。
普通に考えれば、戻されるProcessクラスの情報は「起動した外部プログラムの情報」になると思うのですが、launch命令では、そうではありません。
なぜならlaunch命令は、該当命令が実行されたOSごとに異なる方法で、argsに渡された内容を実行しようとするからです。具体的には、Windowsの場合はコマンドプロンプトへargsで指定された内容を引き渡すことで外部プログラムを起動します。
イメージとしては、「cmd /c args[0]の内容 args[1]の内容 args[2]の内容 …」です。
このため戻されるProcess情報はコマンドプロンプトの情報になります。よって戻されたProcess情報を使って、外部プログラムを制御する事ができません。
例えばlaunch命令実行後に、その外部プログラムが起動しているか調べたり、終了命令を送る事ができないので注意してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
void setup(){ //起動AP名と引数 String args[] = { "C:\\Windows\\notepad.exe", "C:\\temp\\hoge.txt" }; //起動する launch( args ); } void draw(){ } |
例えば上記は、C:¥Windowsにあるnotepad.exeを起動しています。
引数にC:¥temp¥hoge.txtを与えているので、メモ帳が開くと同時に指定したテキストファイルが表示されます。
exec()命令を使う
p:生成されたプロセス情報
args:起動コマンドとパラメータの配列
使い方はlaunch命令と同じです。戻り値には、JavaのProcessクラスが戻されます。
こちらはJavaのRuntime.getRuntime.exec(String[])と同じ動作をしますので、戻されるProcess情報は起動した外部プログラムのものになります。
Process情報を使うと、該当プログラムが起動しているかどうかがわかります。また該当プログラムを終了させることができます。
ただし本当に正確な情報が得られるかどうかや、終了するかどうかは外部プログラム次第です。例えばメモ帳(notepad.exe)や電卓(calc.exe)は制御できましたが、Chromeの場合は起動することはできても制御はできませんでした。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
Process p = null; void setup(){ //起動AP名と引数 String args[] = { "C:\\windows\\notepad.exe", "C:\\temp\\hoge.txt" }; //起動する p = exec( args ); } void draw(){ } void mouseClicked(){ if( p!= null && p.isAlive() ){ //起動中なら終了させる p.destroy(); p = null; } |
上記は、C:¥Windowsにあるnotepad.exeを起動しています。
引数にC:¥temp¥hoge.txtを与えているので、メモ帳が開くと同時に指定したテキストファイルが表示されます。その後マウスクリックを行うと、メモ帳が終了します。
ProcessBuilderを使う
rocessBuilder pb = new ProcessBuilder(String… command);
pb:生成されたProcessBuilder情報
command:起動コマンドとパラメータ
ProcessBuilderクラスを利用するには、起動したいプログラム名と引数を指定して、ProcessBuilder クラスのインスタンスを作成します。
起動したいプログラム名と引数はListで渡すことも可能ですし、Stringをカンマで区切って渡してもOKです。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//起動AP名と引数 ArrayList<String> args = new ArrayList<String>(); args.add("C:\\windows\\notepad.exe"); args.add("C:\\temp\\hoge.txt"); //起動準備 ProcessBuilder pb = new ProcessBuilder( args ); //Listを使わず、以下のようにしてもOK //ProcessBuilder pb = new ProcessBuilder( // "C:\\windows\\notepad.exe", // "C:\\temp\\hoge.txt" //); |
例えば上記のような感じです。
上記例ではArrayListを使って、メモ帳と引数を指定しています。もちろんListを使わずにコメントにあるような記述でもOKです。
.
pb:生成されたProcessBuilder情報
p:生成されたプロセス情報
起動するにはProcessBuilderクラスのstart()メソッドを利用します。成功すると、戻り値にはJavaのProcessクラスが戻されます。失敗すると IOException 例外が発生します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
import java.lang.ProcessBuilder; ProcessBuilder pb = null; Process p = null; void setup(){ //起動AP名と引数 ArrayList<String> args = new ArrayList<String>(); args.add("C:\\windows\\notepad.exe"); args.add("C:\\temp\\hoge.txt"); //起動準備 pb = new ProcessBuilder( args ); //起動する try{ p = pb.start(); } catch( IOException e ){ e.printStackTrace(); } } void draw(){ } void mouseClicked(){ if( p!= null && p.isAlive() ){ //起動中なら終了させる p.destroy(); p = null; } } |
上記は、C:¥Windowsにあるnotepad.exeを起動しています。
引数にC:¥temp¥hoge.txtを与えているので、メモ帳が開くと同時に指定したテキストファイルが表示されます。その後マウスクリックを行うと、メモ帳が終了します。
ProcessBuilderクラスには、この他にも
- 外部プログラムの作業フォルダを指定する
- 外部プログラムの標準入出力先を切り替える
といった、便利なメソッドが用意されています。詳しくは 公式ドキュメント を参照してください。
【関連記事】
- なし
サンプルプログラム
外部プログラムを起動する例:
メインAP:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
/** * PROCESSING 3 外部AP起動Sample * @auther MSLABO * @version 2020/02 1.0 */ import java.lang.ProcessBuilder; import java.io.InputStreamReader; ProcessBuilder pb = null; Process p = null; BufferedReader br = null; void setup(){ //別AP起動(Java AP) ProcessBuilder pb = new ProcessBuilder("java", "-jar", dataPath("SubApSample.jar")); try{ p = pb.start(); } catch( IOException e ){ e.printStackTrace(); } //入力監視を別スレッドにする //※こうしないと、別APが終了するまでbr.readLine()を抜け出さないので // main側の処理がブロックされる事を回避 thread( "inputRead" ); } void draw(){ } //別スレッドで入力を監視して表示する void inputRead(){ //起動できたら、別APの標準出力を読むReader準備 if( p.isAlive() ){ br = new BufferedReader( new InputStreamReader( p.getInputStream() )); //別APの標準出力を読む try{ //このLoopは、別AP稼働中は抜け出さないので注意 for(String line = br.readLine(); line != null; line = br.readLine()) { println( "入力内容は[" + line + "]です"); } } catch( IOException e ){ e.printStackTrace(); } } } void mouseClicked(){ if( p!= null && p.isAlive() ){ //起動中なら終了させる p.destroy(); p = null; } } |
外部AP(サブAP):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
/** * Java 文字入力Sample * @auther MSLABO * @version 2020/02 1.0 */ import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class SubApSample { public static void main(String[] args){ //(1)Windowを作成する JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds( 100, 100,300,150 ); //(2)レイヤー付きパネルを作成する JLayeredPane panel = new JLayeredPane(); //(3)GUIが使う文字を準備する Font font = new Font("MS ゴシック", Font.PLAIN, 14); //(4)部品を作成する JLabel lblName = new JLabel("お名前"); lblName.setFont( font ); final JTextField txtName = new JTextField( "" ); txtName.setFont( font ); JButton btnOk = new JButton("OK"); btnOk.setFont( font ); btnOk.setActionCommand( "OK" ); //(5)GUI部品の大きさや装飾を決定する lblName.setBounds( 0, 10, 16*3, 16 ); txtName.setBounds( 16*3,10, 16*14, 16 ); btnOk.setBounds( 50, 32, 100, 30 ); //(6)イベントリスナーを指定する btnOk.addActionListener( new ActionListener(){ public void actionPerformed(ActionEvent ev ){ String cmd = ev.getActionCommand(); if( cmd.equals( "OK" )){ //OKが押されたら、txtNameの内容を標準出力へ書き込む System.out.println( txtName.getText() ); } } } ); //(7)各部品をレイヤー付きパネルに追加する panel.add( lblName ); panel.add( txtName ); panel.add( btnOk ); //(8)パネルをWindowに追加して表示する frame.add( panel ); frame.setVisible(true); } } |
PROCESSINGで作成したメインAPからJavaで作成した外部APを呼び出しています。
外部AP側で文字を入力し、OKボタンを押下すると、その内容がPROCESSING側に戻されて表示されます。
<出力サンプル>
本ページで利用しているアイコン画像は、下記サイト様より拝借しております。各画像の著作権は、それぞれのサイト様および作者にあります。