将子进程输出重定向到缓冲区 [英] Redirecting Child process output to buffer
问题描述
我正在研究 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屋!