将子进程输出重定向到缓冲区 [英] Redirecting Child process output to buffer

查看:88
本文介绍了将子进程输出重定向到缓冲区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究 Visual Studio C++.我有需要重定向到某个缓冲区的子进程输出.任何人都可以帮我解决这个问题.

I am working on Visual Studio C++. I have child process output which need to be redirected to some buffer.Can anyone please help me out of this.

char ReadBuff[4096 + 1];
DWORD ReadNum;
for (;;) 
{
    BOOL success = ReadFile(pipes[ParentRead], ReadBuff, sizeof(ReadBuff) - 1, &ReadNum, NULL);
    std::cout << success;
    if (!success || !ReadNum)
        break;
    ReadBuff[ReadNum] = 0;
    std::cout << ReadBuff;
}

我已经为 ParentRead, ParentWrite, ChildWrite, ChildRead 创建了句柄.我确实关闭了除 ParentRead 之外的所有句柄.所以,我可以从中读取内容.当我调试它时,它会中断并且成功为 0.谁能告诉我它无法读取文件.非常感谢

I have created handle for ParentRead, ParentWrite, ChildWrite, ChildRead . I did close all the handles except ParentRead. So, I could read the contents from it. When I debug it it breaks and success is 0. can anyone let me know y it couldn't read the file. Thank you very much

推荐答案

这不是我自己的代码,我很久以前就找到了.此处的链接 (http://snipplr.com/view/35935/) 可能不是原始链接源代码,所以我也发布了代码.

this is not my own code, I've found it long ago. the link here (http://snipplr.com/view/35935/) might not be the original source, so I'm posting the code too.

因此此代码将运行一个命令并将所有输出转换为 CString,WaitForSingleObject(pi.hProcess, INFINITE); 将使您的主进程挂起,直到子进程完成.

so this code will run a command and get you all the output into a CString, the WaitForSingleObject( pi.hProcess, INFINITE ); will make your main process hang until the child process is done.

// Execute a command and get the results in a CString.
// Synchronously launches a child process and waits up to 2 seconds for completion.
// Uses a pipe to get the output of the child process.
// Does not pipe to stdin of child process.
// Example usage:
// CString str;
// str = ExecCmd( "ping 127.0.0.1 -n 99 " ); // This ping command will be terminated early before the -n 99 completes.
// str.Replace( "\x0d\x0d\x0a", "\x0d\x0a" ); // fixes some ugly non-standard line terminators created by ping.
//
// str = ExecCmd( "java -version" ); // A more practical usage.
//
CString ExecCmd( CString pCmdArg,CString csParameters, CString csDir)
{
    // Handle Inheritance - to pipe child's stdout via pipes to parent, handles must be inherited.
    // SECURITY_ATTRIBUTES.bInheritHandle must be TRUE
    // CreateProcess parameter bInheritHandles must be TRUE;
    // STARTUPINFO.dwFlags must have STARTF_USESTDHANDLES set.

    CString strResult = L""; // Contains result of cmdArg.

    HANDLE hChildStdoutRd; // Read-side, used in calls to ReadFile() to get child's stdout output.
    HANDLE hChildStdoutWr; // Write-side, given to child process using si struct.

    BOOL fSuccess;

    // Create security attributes to create pipe.
    SECURITY_ATTRIBUTES saAttr = {sizeof(SECURITY_ATTRIBUTES)} ;
    saAttr.bInheritHandle = TRUE; // Set the bInheritHandle flag so pipe handles are inherited by child process. Required.
    saAttr.lpSecurityDescriptor = NULL;

    // Create a pipe to get results from child's stdout.
    // I'll create only 1 because I don't need to pipe to the child's stdin.
    if ( !CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0) )
    {
        return L"cannot create pipe";
    }

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

    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; // STARTF_USESTDHANDLES is Required.
    si.hStdOutput = hChildStdoutWr; // Requires STARTF_USESTDHANDLES in dwFlags.
    si.hStdError = hChildStdoutWr; // Requires STARTF_USESTDHANDLES in dwFlags.
    // si.hStdInput remains null.
    si.wShowWindow = SW_HIDE; // Prevents cmd window from flashing. Requires STARTF_USESHOWWINDOW in dwFlags.

    CString csCommand(pCmdArg);
    csCommand+= L" ";
    csCommand+= csParameters;
    // Create the child process.
    fSuccess = CreateProcess(NULL, csCommand.GetBuffer(0), NULL, NULL, TRUE, 0, NULL,
        csDir, &si, &pi);
//     fSuccess = CreateProcess(
//         NULL,
//         (LPSTR)pCmdArg, // command line
//         NULL, // process security attributes
//         NULL, // primary thread security attributes
//         TRUE, // TRUE=handles are inherited. Required.
//         CREATE_NEW_CONSOLE, // creation flags
//         NULL, // use parent's environment
//         NULL, // use parent's current directory
//         &si, // __in, STARTUPINFO pointer
//         &pi); // __out, receives PROCESS_INFORMATION

    if (! fSuccess)
    {
        return L"cannot create process";
    }

    // Wait until child processes exit. 
    WaitForSingleObject( pi.hProcess, INFINITE );
    TerminateProcess( pi.hProcess, 0 ); // Kill process if it is still running. Tested using cmd "ping blah -n 99"

    // Close the write end of the pipe before reading from the read end of the pipe.
    if (!CloseHandle(hChildStdoutWr))
    {
        return L"cannot close handle";
    }

    // Read output from the child process.
    for (;;)
    {
        DWORD dwRead;
        CHAR chBuf[4096];

        // Read from pipe that is the standard output for child process.
        bool done = !ReadFile( hChildStdoutRd, chBuf, 4096, &dwRead, NULL) || dwRead == 0;
        if( done )
        {
            break;
        }

        // Append result to string.
        strResult += CString( chBuf, dwRead) ;
    }

    // Close process and thread handles.
    CloseHandle( hChildStdoutRd );

    // CreateProcess docs specify that these must be closed.
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );

    return strResult;
}

这篇关于将子进程输出重定向到缓冲区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆