バックグラウンドでプロセスを実行し、プロセス終了と同時に、その終了コードに応じてアクションを実行しなければならないことがあります。4D v19 R4 より、新しい 4D.SystemWorker クラスを使ってバックグラウンドでプロセスを開始し、プロセスが情報を返したときに自動的にコールバックメソッドを実行できるようになりました。この方法では、外部プロセスが実行中でもアプリケーションの UI は応答し続け、終了したらすぐにユーザーに結果を表示することができます!
SystemWorker は、コンストラクター 4D.SystemWorker.new(process) によって作成されるオブジェクトです。引数として渡されたプロセスを開始し、同プロセスの終了まで待機する新しいワーカーを作成します。
ここでは、SystemWorker を使ってさまざまな git コマンドを実行する例をいくつか紹介します。
まずはシンプルに、マシンにインストールされている git のバージョンを取得してみましょう。これには 2つの方法があります。
- 非同期でおこない、クライアントが引き続きインターフェースを自由に使えるようにしたい場合は、プロセス終了時に呼び出されるコールバックを使用します:
$param:=New object
// プロセスがすでに終了していなければ 2秒後にプロセスを閉じます
$param.timeout:=2
// システムワーカーがレスポンスを受領した時に呼び出されるコールバックフォーミュラ
$param.onResponse:=Formula(ALERT($1.response))
// 上に指定した引数でシステムワーカーを起動します
$sys:=4D.SystemWorker.new("git --version"; $param)
- プロセスの応答を待ちたい場合は、.wait() を使います:
$param:=New object
// プロセスがすでに終了していなければ 2秒後にプロセスを閉じます
$param.timeout:=2
// 上に指定した引数でシステムワーカーを起動します
$sys:=4D.SystemWorker.new("git --version";$param)
// プロセス終了まで待機し、Git のレスポンスを返します
ALERT($sys.wait().response)
続けて、コミットメッセージを待機するコミットをしてみましょう。この例では、プロセスは標準的な入力を待ちます。コンソールであれば、コンソールがユーザーの値入力を待つということです:
このような場合には、.postMessage() 関数を使用してメッセージを送信し、.closeInput() 関数を使用してメッセージが送信されたことをプロセスに指示することができます:
$param:=New object
$param.currentDirectory:=$myProjectDirectory
$sys:=4D.SystemWorker.new("git commit -F -";$param)
$sys.postMessage("This is my first commit")
$sys.closeInput()
お気づきのように、システムワーカーは Launch external process コマンドを超えるものです。非同期でプロセスを起動し、呼び出されたプロセスから outputStream と errorStream を簡単に受け取ることができます。さらに、プロセスと通信する新しい方法として .postMessage() 関数を使うことができます。
この機能を上の HDI でテストし、複数のプロセスを並行して起動させる方法を試してみてください。
詳しくはデベロッパーセンターをご覧ください。