// pipe01.c #include <stdio.h> #include <windows.h> int WritePipe(); int MyCreateChildAndPipe(); HANDLE hWrite, hProcess; int end; int main() { char ans[8]; //子プロセスとパイプの作成 MyCreateChildAndPipe(); while (1) { printf("***** Menu *******\n"); printf("1.パイプに書き込む\n"); printf("0.終了\n"); printf("******************\n"); printf("--->"); gets(ans); switch (ans[0]) { case '1': WritePipe(); break; case '0': end = 1; WritePipe(); break; default: printf("入力ミスです\n"); break; } if (end == 1) break; } return 0; }プログラム開始とともに、MyCreateChildAndPipe関数で子プロセスと 匿名パイプを作ります。
次にメニューを表示してユーザーに指示を促します。
ここでは、書き込みをするのか、終了するのかを選択します。
書き込みをする場合はWritePipe関数を呼んで書き込みをします。
さて、終了時にはendグローバル変数を1にして、WritePipe関数を呼びます。
これは、終了時にちょっとした細工をするためです。
int WritePipe() { char szBuf[256]; DWORD dwResult, dwError; if (end != 1) { printf("書き込みをしてください--->"); gets(szBuf); } else { strcpy(szBuf, "end"); } if (!WriteFile(hWrite, szBuf, sizeof(szBuf), &dwResult, NULL)) { dwError = GetLastError(); if (dwError == ERROR_BROKEN_PIPE || dwError == ERROR_NO_DATA) { printf("パイプがありません\n"); } else { printf("何らかのエラーです\n"); } CloseHandle(hWrite); hWrite = NULL; CloseHandle(hProcess); hProcess = NULL; return -1; } return 0; }パイプに書き込みをする関数です。
グローバル変数のendが1の時は、パイプに"end"と書き込みます。
これが、終了の合図となります。
endが1でないときは、ユーザーに書き込みを促します。
WriteFile関数でパイプに書き込みを行います。
int MyCreateChildAndPipe() { HANDLE hRead; SECURITY_ATTRIBUTES sa; STARTUPINFO si; PROCESS_INFORMATION pi; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; if (!CreatePipe(&hRead, &hWrite, &sa, 0)) { printf("パイプの作成に失敗しました\n"); return -1; } if (!DuplicateHandle(GetCurrentProcess(), //ソースプロセス hWrite, //duplicateするハンドル(オリジナルハンドル) GetCurrentProcess(), //ターゲットプロセス(行先) NULL, //複製ハンドルへのポインタ(コピーハンドル) 0, //アクセス権 FALSE, //子供がハンドルを継承するかどうか DUPLICATE_SAME_ACCESS)) { //オプション printf("DuplicateHandle Error\n"); CloseHandle(hWrite); CloseHandle(hRead); hWrite = NULL; return -2; } memset(&si, 0, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.dwFlags = STARTF_USESTDHANDLES; si.hStdInput = hRead; si.hStdOutput = GetStdHandle( STD_OUTPUT_HANDLE ); si.hStdError = GetStdHandle( STD_ERROR_HANDLE ); if (!CreateProcess(NULL, "pipe01child.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) { printf("CreateProcess Error\n"); CloseHandle(hWrite); hWrite = NULL; return -3; } hProcess = pi.hProcess; CloseHandle(pi.hThread); CloseHandle(hRead); return 0; }パイプと、子プロセスを作成する関数です。
DuplicateHandle関数の意味がわかりにくいので、前章でもう一度復習しておいて ください。
さて、このプログラムのみではうまく動作しません。これとは、別に"pipe01child.exe" という名前のプログラムが必要です。
親プロセスから書き込みをした内容がパイプを通じてpipe01child.exeに送信されます。
次回は、pipe01child.exeを作ります。
Update Feb/09/2006 By Y.Kumei