ffmpeg 등 command line 툴의 콘솔 출력을 잡기 위해선 pipe 를 이용하여
std-in, std-out, std-err 를 redirection 해야한다.
redirection 은 fprintf(stdout)..., printf, fgets 등의 표준 I/O 의 목적지를 화면이 아닌 모(母) 프로그램이 받도록 도와준다.
Win32 함수로 구현하기 위해선 CreatePipe, Duplicate, ReadFile, WriteFile, CloseHandle 함수를 사용해야 한다.
여러 프로그램을 pipe 로 연결시킨 경우 각각의 프로세스를 만들고 앞 프로세스의 output 을 다음 프로세스의 input 에 수동으로 넣어줘야 한다. 난 당연히 자동으로 되겠지 했으나 왜 그런지 에러만 났을 뿐이다.
CreatePipe(&ReadFromOutput, &WriteToOutput, nullptr, PIPE_LENGTH);
CreatePipe(&ReadFromError, &WriteToError, nullptr, PIPE_LENGTH);
DuplicateHandle( GetCurrentProcess(), ReadFromInput, GetCurrentProcess(), &exec.hInput, 0, TRUE, DUPLICATE_SAME_ACCESS);
DuplicateHandle( GetCurrentProcess(), WriteToOutput, GetCurrentProcess(), &exec.hOutput, 0, TRUE, DUPLICATE_SAME_ACCESS);
DuplicateHandle( GetCurrentProcess(), WriteToError, GetCurrentProcess(), &exec.hError, 0, TRUE, DUPLICATE_SAME_ACCESS);
DuplicateHandle( GetCurrentProcess(), WriteToInput, GetCurrentProcess(), &exec.hWriteToFFMPEG, 0, FALSE, DUPLICATE_SAME_ACCESS);
DuplicateHandle( GetCurrentProcess(), ReadFromOutput, GetCurrentProcess(), &exec.hReadFromFFMPEG, 0, FALSE, DUPLICATE_SAME_ACCESS);
DuplicateHandle( GetCurrentProcess(), ReadFromError, GetCurrentProcess(), &exec.hReadFromFFMPEGError, 0, FALSE, DUPLICATE_SAME_ACCESS);
CloseHandle( WriteToInput ); WriteToInput = NULL;
CloseHandle( ReadFromOutput ); ReadFromOutput = NULL;
CloseHandle (ReadFromError); ReadFromError = NULL;
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
STARTUPINFO si;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = exec.hInput;
si.hStdOutput = exec.hOutput;
si.hStdError = exec.hError;
SetLastError(0);
TCHAR CommandLine[10240];
_tcscpy_s(CommandLine, cei.CommandLine);
...
launch_ok = CreateProcess(nullptr, CommandLine, nullptr, nullptr, TRUE, CREATE_NO_WINDOW, (LPVOID)my_env_param, nullptr, &si, &pi);