- 注
-
基礎知識として基礎編マニュアルの、外部プログラムの実行 のセクションを先にお読みいただき、そのあと本章をお読みください。
外部プログラムの実行は、コンソールアプリケーションであれば
「プログラム実行」 が代表的なものですが、GUIアプリケーションでは
「プログラム実行」 は定義されておらず使えません。この処理単語によって外部プログラムを起動すると、そのプログラムが終了するまで戻って来ず、その間はGUIが反応できなくなってしまう(フリーズしたかのようになる)ためです。
GUIアプリケーションではそれに代わって
「子プロセス起動」系統 の処理単語を使います。こちらであれば外部プログラム実行中もイベント処理が行われ、キーボードやマウスに反応できます。
この系統の解説は、基礎編マニュアルの、
「外部プログラムの実行」−「シェルを経由しない子プロセス起動」 にありますが、以下では特にGUIアプリケーションにおける補足を解説します。
外部プログラムの呼び出し手段
基本的には
「子プロセス起動」 を使ってください。これはプロセスをキックするだけで直ちに戻って来ます。もしその外部プログラムの結果を待って次の処理をしたい場合には、
「子プロセス実行」 のほう使ってください。
「子プロセス実行」 の中で外部プログラムの終了を待ちますが、ライブラリの待ちループ内でGUIイベントを処理する仕組みが入っているので、待っている間にGUIアプリケーションが止まってしまうことはありません。
「子プロセス終了を待つ」 でも同様です。
- 注
- GUIアプリケーションからコンソールアプリケーションを起動する場合はここでの解説とは別に、処理単語「非同期のパイプを使いプログラムを実行」を使うことを強く勧めます。
開発の後の段階で実装されたのでマニュアルが別になっています。Mind WorkBench を立ち上げ、
「ヘルプ」−「Mind WorkBenchのプログラム解説」−
「11.実行」−
処理単語「非同期のパイプを使いプログラムを実行」
をお読み願います。
cmd.exe経由の起動
■cmd.exe経由の起動が必要になるケース
-
「子プロセス起動」系統の起動ではコマンドプロセッサである cmd.exe を経由しないため、たとえば cd コマンド、ver コマンドなどのビルトインコマンドは実行できません。
-
GUIアプリからコンソールアプリを起動するとき、そのコンソールアプリが 「何らかの情報を表示して直ちに終了する」 タイプである場合に、コンソールアプリの走行のため開いたウィンドウがすぐ消えてしまうので肝心の情報を読むことができません。
たとえば、Mind 9 ディレクトリの sample\ 内にある hello.exe を起動したとき、「こんにちは」というメッセージが表示されるはずなのですが一瞬すぎて見ることができません(何かウィンドウが開いたような気がする・・という程度の短い時間です)。
上記いずれかのケースも、あえて cmd.exe を経由して起動することて解決します。
■cmd.exe経由の起動
構文=
(外部プログラム終了と共にウィンドウを閉じる)
"cmd /c プログラム名 [引数]"を 子プロセス起動 → プロセスID
(外部プログラム終了後もコマンド プロンプト画面を維持する)
"cmd /k プログラム名 [引数]"を 子プロセス起動 → プロセスID
記:「子プロセス実行」についても同様です。
その場合は、戻値が「→ ・」となります。
記:プログラム名の拡張子は省略できますが付けたほうが、
ソースコード上から .exe/.bat の区別が付き好ましいです。
上記には2タイプの起動方法がありますが、後者が多くの用途に使えます。
後者(cmd /k から始まる)では、コンソールアプリケーション終了後もコマンド プロンプトの画面に留まるため表示された情報を読むことができます。読み終わったら exit コマンドを入力するとコンソールウィンドウが閉じ、呼び出し主であるGUIアプリケーションに制御が戻ります。
一方、コンソールアプリケーションが起動するとユーザとの対話に入るようなものでは、ウィンドウが直ちに閉じるわけではないため、単純に「子プロセスを起動」「子プロセスを実行」を使うことができます。
cmd.exe経由する/しないを問わず注意
■GUIアプリからGUIアプリを起動する場合
GUIアプリケーションから別のGUIアプリケーション(Mind記述かは問わず)を起動するケースですが、多くの場合は終了を待たない使い方となると思います。GUIアプリケーションは起動している時間が比較的長く、終了を待つことにあまり意味が無いと思われるからです。この場合は「子プロセス起動」を使うことを勧めます。
もし、別のGUIアプリケーションが終了することを待って何かをおこないたいことがあるなら、「子プロセス実行」のほうを使ってください。
あるいは、「子プロセス起動」で起動した後、時々「子プロセス終了?」で終了をチェックする方法もあります。
■パス検索
「子プロセス起動」と、「子プロセス実行」を問わず、また、cmd経由かどうかを問わず、外部プログラムの起動にあたってユーザ独自のPATH環境変数の検索は行われないため、パス無しでプログラムを起動することはできず、必ずパス指定をしてください(Windowsのシステム環境変数としての PATH は検索されます)。
パス指定は相対パスでもおこなえるため、たとえば、自身のGUIプログラム(.exeファイル)と同じフォルダ内にある外部プログラムを起動するなら、
.¥your_program.exe
のような相対パスを指定しても構いません。(注:この先の解説、
自身のカレントディレクトリ もお読みください)
■プログラム名または引数に空白を含む場合
外部プログラム名に空白を含む場合、あるいは引数に空白を含む場合は、個々にダブルクオート記号で囲んで "〜〜" のようにしてください。(ディレクトリ "c:¥Program Files" などは要注意です)
そのようなダブルクオート含みの文字列定数をMindのソースコードに記述する場合は、
(例) ↓パスに空白あり ↓引数に空白あり
「"c:\path to\myprog.exe" "山田 太郎"」を 子プロセス起動し ・・
のように書けば "〜" と 「〜」 が両立でき、干渉せずに済みます。
■「遅延」との競合
「子プロセス実行」および「子プロセス終了を待つ」は、内部的に処理単語「遅延」を使っているため、それにまたがるタイミングでユーザもまた「遅延」を使うと大きな誤差が出ることがあります。これは「n秒待ち」系の単語も同様です。
そのようなケースで確実に遅延するには「遅延」ではなく「遅延実行」を使うなど対策をしてください。
■コンソールアプリケーションを起動してウィンドウが開くこと
起動する外部プログラムがコンソールアプリケーションの場合、そのアプリケーションが表示するメッセージを見る必要が無い場合であってもコンソールウィンドウが開いてしまいます。短い表示であればウィンドウが開く時間もごくわずかですが、仕様上これは抑制できませんがご承知ください。
なお、Mind WorkBench における外部プログラム起動(コンソール系アプリケーションの場合)では特別な機能を使うことでこの問題を回避しています。詳しくは、Mind WorkBench の「ヘルプ」−「Mind WorkBench のプログラム解説」の、
11.実行
処理単語「非同期のパイプを使いプログラムを実行」
をお読みください。
外部プログラムの実行のサンプルプログラム
- exec-program.src
- リストから選んだ外部プログラム(GUIアプリケーション)を実行します。プログラム名はキーボードからも指示できます。
「子プロセス起動」と「子プロセス終了を待つ」をセットで使っています。
- exec-process-use-asyncpipe.src
- リストから選んだ外部プログラム(コンソールアプリケーション)を実行します。起動した子プロセスが出力した文字列を引き取ってモニタ域に表示します。
処理単語「非同期のパイプを使いプログラムを実行」は、子プロセスを起動するときに親子間でパイプを張り、子プロセスからの標準出力を親プロセスで吸い上げることができます。
なぜこのような仕組みが必要かと言えば、コンソールアプリケーションはコマンド プロンプトなどのターミナル配下で動作するように作られており、表示データは通常の方法ではGUIアプリケーション側で得ることができないからです。
「非同期のパイプを使いプログラムを実行」の使い方は、Mind WorkBench の
「ヘルプ」−「Mind WorkBench のプログラム解説」−
11.実行
処理単語「非同期のパイプを使いプログラムを実行」
をお読みください。
■起動時の引数
エクスプローラで自プログラムのexeファイルをダブルリクックして起動する場合は引数を付けられませんが、以下の方法で引数付きで起動できます。
(1) コマンド プロンプトから、
>start MYPROG 引数・・
のように起動する(startを付けないと次のコマンド待ちにならない)
(2) ショートカットを作成する方法
デスクトップあるいは任意のフォルダ内にexeファイルの
ショートカットを作成し、ショートカットのプロパティを
開き、プログラム名の直後に引数を記入する
(3) 他のプログラムから自プログラムを起動
バッチファイルまたは他のプログラムから、スクリプトとして
自プログラムを起動する
上記により渡された起動引数は自プログラムにおいて、コンソールアプリケーションと同様に「起動引数個数」「起動引数(n)」によって参照できます。
自プログラムを単純起動した時とは異なる動作モードを与えたい場合にこの方法が使えます。
■自身のカレントディレクトリ
GUIアプリケーションはエクスプローラで .exe ファイルをダブルクリックして起動することが多いと思います。その場合はアプリケーション起動時のカレントディレクトリは .exe ファイルの存在場所となります。しかし、多くがそうだからといって、それを前提としないでください。
GUIアプリケーションが他の手段で起動されることかあります。たとえばコマンド プロンプトから次のようにパス付きで起動されることがあります。
>start c:\dir\MYAPP
あるいは他のアプリケーションから動的に起動されることもあります。
このようなケースではカレントディレクトリはコマンド プロンプト作業中のディレクトリであったり、他のアプリケーションの存在場所であったりと、いずれにしても自己の .exe ファイルの存在場所にはなりません。この点に注意してください。
もし自己の .exe ファイルの存在場所を明にカレントディレクトリにしたいのであれば、「メインとは」冒頭で次のコードを書くことでおこなってください。
↓これにより自己のexeファイル存在場所がカレントディレクトリになります
私のパス名を カレントディレクトリ設定する