ここでは、ある(親)プロセスの中で、別の(子)プロセスを実行をします。
まず、子プロセスとなるプログラムを作ります。
#include <stdio.h> int main(void) { printf("child is called.\n"); return 0; }
なんてことはない、Hello Worldプログラムと一緒ですね。
これをコンパイルして出来た実行ファイルを「child.exe」としておきます。
では、本題の親となるプログラムを作ります。
まずは前半部分の、main関数です。
#include <stdio.h> #include <windows.h> int execute(LPTSTR commandLine); int main() { LPTSTR commandLine = TEXT("child.exe"); //子プログラム int r; printf("parent start.\n"); r = execute(commandLine); printf("parent end.\n"); return r; }
windows.h>をインクルードすることで、LPTSTR型やTEXT関数などが使えています。
WinAPIの「お約束」みたいなものだと思うので、気にしないでください。
(気になった人は各自調べてみてください)
commandLineには実行するプログラムの名前が入っています。
execute関数だけは、自分で定義しています。この中身を確認していきます。
int execute(LPTSTR commandLine) { HANDLE childProcess = NULL; STARTUPINFO si = { sizeof(STARTUPINFO) }; PROCESS_INFORMATION pi = {}; if (!CreateProcess( commandLine, //実行するファイル名 NULL, //実行時引数の指定 NULL, //プロセスのセキュリティー記述子 NULL, //スレッドのセキュリティー記述子 FALSE, //ハンドルを継承しない(子は親を操作できない) 0, //作成フラグ NULL, //環境変数は引き継ぐ NULL, //カレントディレクトリーは同じ &si, &pi)) { return -1; } // 子プロセス起動成功 childProcess = pi.hProcess; // 不要なスレッドハンドルをクローズする if (!CloseHandle(pi.hThread)) { return -1; } // 子プロセスの終了待ち DWORD r = WaitForSingleObject(childProcess, INFINITE); // 子プロセスの終了コードを取得、出力 DWORD exitCode; if (!GetExitCodeProcess(childProcess, &exitCode)) { return -1; } printf("exitCode=%d/%x\n", exitCode, exitCode); CloseHandle(childProcess); return exitCode; }
HANDLE や STARTUPINFO 、 PROCESS_INFORMATION は、子プロセスを作成するために必要なものなので、深く考えないほうがいいです。
同じく、createProcess関数の引数も1番目と2番目以外は考える必要はないと思います。
1番目に実行ファイルの名前を、2番目に実行時引数を文字列で与えます。
子プロセスの起動に成功したら、子プロセスのスレッドハンドルは不要なので閉じ、子プロセスの終了を待ちます。
子プロセスが終了したら、終了コード(子プロセスのmainからの返り値)を取得して、子プロセスのハンドルを閉じます。
終了コードが必要ないならば、取得する必要はありません。
最後にこのプログラムの実行結果を確認します。
2つの実行ファイルを同じフォルダに入れて親側のプログラムを実行させます。
parent start. child is called. exitCode=0 parent end.
親プロセスの中で、子プロセスが呼び出されているのがわかりますね。
前回:なし 次回:パイプを使って通信する