2012-06-24 39 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

相关问题