2012-06-24 54 views
1

我幾天來一直在尋找關於這個問題的答案,我希望你們能夠幫助我。 (我搜索並找到了一些解決方案,但每個都有自己的問題...)。在cpp中重定向stdout輸出

這是事: 我正在寫一個自動化工作,它負責啓動由我的同事編寫的代碼的外部「.exe」文件。由於他們寫的這些程序都是客戶,所以我不允許對其代碼進行任何修改。這些程序一旦啓動,正在等待特定的擊鍵,並在收到合法的擊鍵時打印一條消息。

我的目標是這樣的: 要編寫一個程序,它將執行外部程序,發送它的按鍵,並從它們的stdout接收輸出。 到目前爲止,我已經能夠從我的程序(使用ShellExecute)運行程序,並將某種鍵盤監聽器(使用SendMessage)模擬到其他程序。我可以看到它的工作原理 - 我可以在測試程序的控制檯中看到輸出。

我試圖實時獲取打印在測試程序外殼上的消息(並在程序終止時獲取大量數據),以便在出現問題時對其進行分析。

那些我已經試過:

  • 寫作與在線輸出重定向一個外部批處理文件到一個文本文件。
  • 使用freopen。
  • 執行「ShellExecute」時重定向輸出。
+0

同時使用的ShellExecute你不能重定向輸出。 .net中的類似機制: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函數創建進程以獲取該句柄。 示例代碼 - 不完全爲你的情況,但如何做到這一點很好的例子:

#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是一個輸入參數,用於提供創建進程的選項,而不是輸出參數,它將接收有關創建的進程的任何信息。在上面的示例中調用CreateProcess之後,STARTUPINFO.hStdInput等將全部爲NULL--它不起作用。 –

+0

小心將文字或常量傳遞給CreateProces()。由於CreateProcess()將臨時寫入此位置,因此這是一個常見的必須,並導致未定義的行爲。在這裏看到答案:http://stackoverflow.com/questions/9427008/what-should-the-second-parameter-of-createprocess-be – namezero

相關問題