更新質問:私はプロセスを作成し、コンパイルするプログラムを入手することができました。しかし、私は新しい問題にぶつかります。ソースプログラムをフィルタプログラムにパイプするとき。シンクプログラムの入力にはフィードがないようです。エラーメッセージはありません。私はまた、Windowsのcmdでパイプ演算子を使って私のスタンドアローンプログラムをすべてテストしました。プロセスと匿名パイプの作成
私はこの小さなプロジェクトを匿名パイプについて学び、プロセスを作成しようとしています。 Source、Filter、Sinkという3つの小さなスタンドアロンプログラムを作成しました。これら3つはすでにコンパイルされており、うまく動作しています。ここでは、3つのスタンドアローンプログラムについて説明します。
ソース:コマンドラインからソーステキストファイルfilenameを取得し、ファイルを開き、一度に1文字ずつファイルを読み込んで標準出力(stdout)に直接コピーします。ファイルがコピーされると、Sourceは終了します(開いているファイルハンドルをすべて閉じます)。
フィルタプログラムは、ファイル名のコマンドラインパラメータを使用しません。代わりに、Filterは標準入力(stdin)からテキストファイルを読み込み、すべての大文字を小文字に変換した入力のコピーを標準出力(stdout)に書き込みます。フィルターは、入力データが終了するまで、1文字を読み取り、変換し、出力し、ループするように特別に設計する必要があります。
シンクプログラムは、コマンドラインから宛先テキストファイルのファイル名を取得し、書き込み用にファイルを開き、標準入力ファイル(stdin)から一度に1文字ずつ読み込み、各受信文字を宛先シンクファイルに直接書き込みます。
次の2つのパイプを作成し、指定された同時実行とデータフローを実行するように構成された入力と出力を持つ3つの独立した子を生成するメインドライバプログラムを別々に駆動しています。
: - >ソース - > PIPE1 - >フィルタ - > PIPE2 - - >シンク>destfileドライバプログラムは、2つのコマンドラインパラメータを必要とします
- はSRCFILE:このような何かSRCFILEは、既存のデータのテキストファイルです
C:\> Driver.exe srcfile destfile
、 destfileはシンクアプリケーションによって作成される新しいデスティネーションファイルのファイル名です。
ここに私のドライバプログラムのコードがあります。それはまだ終わっていない。しかし、私は、ソースプログラムのプロセスを作成しようとするときにちょっとした問題に遭遇しました。
更新されたコードは:
#include <windows.h> #include <WinBase.h> #include <stdio.h> #define DELAY_A_WHILE() {volatile long j; for(j = 1; j< 10000; j++) ; } int main(int argc, char *argv[]) { HANDLE hPipeRead, hPipeWrite, hPipeRead2, hPipeWrite2; STARTUPINFO StartupInfoSource; STARTUPINFO StartupInfoFilter; STARTUPINFO StartupInfoSink; PROCESS_INFORMATION ProcInfoSource; PROCESS_INFORMATION ProcInfoFilter; PROCESS_INFORMATION ProcInfoSink; SECURITY_ATTRIBUTES PipeAttributes; SECURITY_ATTRIBUTES PipeAttributes2; char cmdline[200]; PipeAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); PipeAttributes.lpSecurityDescriptor = NULL; //ignore PipeAttributes.bInheritHandle = TRUE; //child can inherit //Create first pipe if (!CreatePipe(&hPipeRead, &hPipeWrite, &PipeAttributes, 0)) { fprintf(stderr, "Error creating pipe: %d\n", GetLastError()); exit(1); } sprintf_s(cmdline, 200, "Source.exe %s", argv[1]); printf("Create process: %s\n", cmdline); GetStartupInfo(&StartupInfoSource); StartupInfoSource.dwFlags = StartupInfoSource.dwFlags | STARTF_USESTDHANDLES; //Mapping StartupInfoSource.hStdInput = GetStdHandle(STD_INPUT_HANDLE); StartupInfoSource.hStdOutput = hPipeWrite; StartupInfoSource.hStdError = GetStdHandle(STD_ERROR_HANDLE); if (!CreateProcess( NULL, cmdline, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &StartupInfoSource, &ProcInfoSource)) { fprintf(stderr, "Error creating child process: %d",GetLastError()); exit(1); } CloseHandle(hPipeWrite); CloseHandle(ProcInfoSource.hProcess); CloseHandle(ProcInfoSource.hThread); PipeAttributes2.nLength = sizeof(SECURITY_ATTRIBUTES); PipeAttributes2.lpSecurityDescriptor = NULL; //ignore PipeAttributes2.bInheritHandle = TRUE; //child can inherit //Create Second Pipe if (!CreatePipe(&hPipeRead2, &hPipeWrite2, &PipeAttributes2, 0)) { fprintf(stderr, "Error creating pipe: %d\n", GetLastError()); exit(1); } GetStartupInfo(&StartupInfoFilter); StartupInfoFilter.dwFlags = StartupInfoFilter.dwFlags | STARTF_USESTDHANDLES; //Mapping StartupInfoFilter.hStdInput = hPipeRead; StartupInfoFilter.hStdOutput = hPipeWrite2; StartupInfoFilter.hStdError = GetStdHandle(STD_ERROR_HANDLE); sprintf_s(cmdline, 200, "Filter.exe"); printf("Create process: %s\n", cmdline); //Filter GetStartupInfo(&StartupInfoFilter); if (!CreateProcess( NULL, cmdline, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &StartupInfoFilter, &ProcInfoFilter)) { fprintf(stderr, "Error creating child process: %d", GetLastError()); exit(1); } // int exitStatus; // GetExitCodeProcess(ProcInfoFilter.hProcess, &exitStatus); CloseHandle(hPipeRead); CloseHandle(hPipeWrite2); CloseHandle(ProcInfoFilter.hProcess); CloseHandle(ProcInfoFilter.hThread); GetStartupInfo(&StartupInfoSink); StartupInfoSink.dwFlags = StartupInfoSink.dwFlags | STARTF_USESTDHANDLES; //Mapping StartupInfoSink.hStdInput = hPipeRead2; StartupInfoSink.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); StartupInfoSink.hStdError = GetStdHandle(STD_ERROR_HANDLE); sprintf_s(cmdline, 200, "Sink.exe %s", argv[2]); printf("Create process: %s\n", cmdline); GetStartupInfo(&StartupInfoSink); if (!CreateProcess( NULL, cmdline, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &StartupInfoSink, &ProcInfoSink)) { fprintf(stderr, "Error creating child process: %d", GetLastError()); exit(1); } CloseHandle(hPipeRead2); CloseHandle(ProcInfoSink.hProcess); CloseHandle(ProcInfoSink.hThread); return 0; }
プログラムは罰金コンパイルします。ただし、プロセスを作成しようとすると、常に失敗して終了します。
cmdline
の値は、 "Source.exe test.txt"です。これは、スタンドアロンソースプログラムを実行するために使用したものです。誰かが私のCreateProcess
が失敗する理由を説明できますか?それは間違ったパラメータを解析するためですか?
あなたは 'CreateProcess'が失敗すると言っていますか?次に、GetLastErrorによって返されたエラーコードを調べる必要があります。ところで、呼び出しプロセスの 'STARTUPINFO'を渡すのは正しいですか? stdinとstdoutにハンドルを渡すのですか? –
私はデバッグしようとすると、プログラムの作成と終了に失敗したときにエラーを出力するif(!CreateProcess())の中で、プログラムは常にそのチャンクを実行します。 –