요약하면,
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 가 도움이 될것이다.
댓글 없음:
댓글 쓰기