요약하면,
1. 프로세스간 통신용 파이프(pipe)를 만들고, 자식 프로세스의 표준출력 핸들을 연결해 놓자.
2. 오랜된 모듈(.exe 등)을 새로운 자식 프로세스로 만든다. 이때 표준 출력등의 핸들을 사용할수있도록 설정해 놓자.
3. 자식 프로세스에서 발생되는 표준출력/에러는 부모프로세스의 파이프로 전달된다.
// ------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
::SECURITY_ATTRIBUTES sa = { 0, };
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = true;
sa.lpSecurityDescriptor = NULL;
HANDLE ReadPipeHandle, WritePipeHandle;
if (!::CreatePipe(&ReadPipeHandle, &WritePipeHandle, &sa, 0))
return FALSE;
::STARTUPINFO si = { 0, };
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
si.hStdOutput = WritePipeHandle;
si.hStdError = WritePipeHandle;
::PROCESS_INFORMATION pi = { 0, };
TCHAR szCmd[MAX_PATH] = { 0, };
_stprintf(szCmd, _T("C:\\Windows\\System32\\cmd.exe"));
TCHAR szArgs[MAX_PATH * 2] = { 0, };
_stprintf(szArgs, _T("C:\\Windows\\System32\\cmd.exe"));
if (!::CreateProcess(szCmd, szArgs, NULL, NULL, true, 0, NULL, NULL, &si, &pi))
return FALSE;
BOOL bSuccess = FALSE;
CHAR cData[4096] = { 0, };
for (;;)
{
DWORD dwBytesRead, dwTotalBytes, dwBytesLeft;
if (!PeekNamedPipe(ReadPipeHandle, cData, sizeof(cData), &dwBytesRead, &dwTotalBytes, &dwBytesLeft))
return FALSE;
if (dwBytesRead)
{
if (!::ReadFile(ReadPipeHandle, cData, sizeof(cData) - 1, &dwBytesRead, NULL))
return FALSE;
cData[dwBytesRead] = '\0';
}
else
{
if (WAIT_OBJECT_0 == WaitForSingleObject(pi.hProcess, 0))
{
bSuccess = TRUE;
break;
}
}
}
::CloseHandle(pi.hThread);
::CloseHandle(pi.hProcess);
::CloseHandle(ReadPipeHandle);
::CloseHandle(WritePipeHandle);
return 0;
}
// ---------------------------ps. 보통 레거시 모듈은 유니코드가 아닌 ANSI 기반인 경우가 많다. ANSI/UNICODE 여부를 알아야 한다면, ::IsTextUnicode 등의 API 가 도움이 될것이다.
