2012-06-24 3 views
1

저는 며칠 동안이 문제에 대한 답변을 찾고 있었으며, 저를 도와 주실 수 있기를 바랍니다. (나는 몇 가지 해결책을 찾았지만 발견했다. 그러나 각각은 그것의 자신의 문제를 가지고있다 ...).cpp에서 stdout 출력을 리디렉션

여기에있는 것이 있습니다 : 직장 동료가 작성한 코드의 외부 ".exe"파일을 시작하는 작업을 자동화하고 있습니다. 그들이 작성한 프로그램이 고객에게 전달됨에 따라 코드 수정이 허용되지 않습니다. 일단 시작된 프로그램은 특정 키 스트로크를 기다리고 있으며 합법적 인 키 스트로크가 수신되면 메시지를 인쇄합니다.

내 목표는 외부 프로그램을 실행할 프로그램을 작성하고 키 스트로크를 보내고 stdout에서 출력을 수신하십시오. 지금까지 필자는 (ShellExecute를 사용하여) 내 프로그램에서 프로그램을 실행하고 다른 프로그램에 키보드 리스너 (SendMessage 사용)를 시뮬레이트했습니다. 나는 그것이 작동하는 것을 볼 수 있습니다 - 나는 테스트 된 프로그램의 콘솔에서 출력을 볼 수 있습니다.

테스트 된 프로그램의 셸에 인쇄 된 메시지를 실시간으로 가져와 (프로그램이 끝나면 대량의 데이터를 얻으려고합니다.)이를 통해 분석 할 수 있습니다.

내가 시도한 경우 : 텍스트 파일로 인라인 출력 리디렉션 외부 배치 파일을 작성

  • .
  • freopen 사용.
  • "ShellExecute"를 실행하는 동안 출력을 리디렉션합니다.
+0

당신은 출력을 리디렉션 할 수 없습니다. 닷넷의 비슷한 메커니즘 : http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardoutput.aspx – Mohammad

+0

[C++에서 다른 프로세스의 stdout 읽기] 가능한 복제본 (http : // stackoverflow .com/questions/4093252/read-another-process-stdout-in-c) –

답변

0

stdin, stdout 및 stderr 핸들을 사용합니다. 핸들을 얻기 위해 CreateProcess 함수로 프로세스를 생성하십시오. 샘플 코드 - 귀하의 경우 불완전하지만, 그것을 수행하는 방법의 좋은 예 :에서 ShellExecute를 사용하는 동안

#include <windows.h> 
#include <stdio.h> 
#include <tchar.h> 

    /*for test.exe 
#include <iostream> 
#include <string> */ 

void _tmain(int argc, TCHAR *argv[]) 
{ 
    /*for test.exe 
    std::cout << "test output" << std::endl; 
    for (;;) 
    { 
     std::string line; 
     std::getline(std::cin, line); 
     std::cout << "line: " << line << std::endl; 
    } 
    return;*/ 
    STARTUPINFO si; 
    PROCESS_INFORMATION pi; 

    ZeroMemory(&si, sizeof(si)); 
    si.cb = sizeof(si); 
    ZeroMemory(&pi, sizeof(pi)); 

    // Start the child process. 
    if(!CreateProcess(NULL, // No module name (use command line) 
     "test.exe",  // Command line 
     NULL,   // Process handle not inheritable 
     NULL,   // Thread handle not inheritable 
     FALSE,   // Set handle inheritance to FALSE 
     0,    // No creation flags 
     NULL,   // Use parent's environment block 
     NULL,   // Use parent's starting directory 
     &si,   // Pointer to STARTUPINFO structure 
     &pi)   // Pointer to PROCESS_INFORMATION structure 
    ) 
    { 
     printf("CreateProcess failed (%d)\n", GetLastError()); 
     return; 
    } 

    /*  HANDLE hStdInput; 
    HANDLE hStdOutput; 
    HANDLE hStdError;*/ 
    HANDLE me_hStdInput = GetStdHandle(STD_INPUT_HANDLE); 
    HANDLE me_hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); 
    HANDLE proc_hStdInput = si.hStdInput; 
    HANDLE proc_hStdOutput = si.hStdOutput; 

       char buff[64]; 
       DWORD chars; 
    while (!ReadConsole(me_hStdInput, buff, sizeof(buff), &chars, NULL)) 
    { 
        for (DWORD written = 0, writtenThisTime; written < chars; written += writtenThisTime)     
         if (!WriteConsole(proc_hStdOutput, buff + written, chars - written, &writtenThisTime, NULL)) 
         { 
          //handle error - TODO 
         } 
       } 
       //possibly handle error for ReadConsole - TODO 


    // Wait until child process exits. 
    //WaitForSingleObject(pi.hProcess, INFINITE); 

    // Close process and thread handles. 
    CloseHandle(pi.hProcess); 
    CloseHandle(pi.hThread); 
} 
+0

STARTUPINFO는 생성 된 프로세스에 대한 정보를 수신하는 출력 매개 변수가 아닌 프로세스를 만드는 옵션을 제공하는 데 사용되는 입력 매개 변수입니다. STARTUPINFO.hStdInput 등은 위의 예제에서 CreateProcess를 호출 한 후에 모두 NULL이됩니다. 작동하지 않습니다. –

+0

리터럴 또는 상수를 CreateProces()로 전달할 때주의하십시오. 그것은 공통적 인 일이며 CreateProcess()가 일시적으로이 위치에 쓸 이후 정의되지 않은 동작이 발생합니다. 답변보기 : http://stackoverflow.com/questions/9427008/what-should-the-second-parameter-of-createprocess-be – namezero

관련 문제