2015년 5월 31일

콘손 출력 문자열의 리다이렉션

새로운 모듈을 개발하다보면, 오래된(legacy) 시스템이나 모듈을 재사용해야 할 경우가 많은데, 오래된 모듈에서 나오는 최종 결과가 문자열과 같이 고정된 형태만 제공한다면, 이를 전달받아 내 마음대로 처리해야 하고자 할때, 문자열을 리다이렉션하여 처리가 가능하다.



요약하면,
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 가 도움이 될것이다.


시리우스 라이브러리 홈페이지 오픈

현재 시리우스(Sirius) 라이브러리라는 제품을 개발하고 이를 소개하는 홈페이지를 오픈 하였습니다. 관심있는 분들의 많은 방문 요청드립니다. 앞으로 업데이트 소식및 변경사항은 스파이럴랩 홈페이지를 통해 진행할 예정입니다. 스파이럴랩 홈페이지 :  h...