我正在使用Visual Studio C ++。我有子进程输出需要重定向到某个缓冲区。任何人都可以帮助我解决这个问题。
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.任何人都可以让我知道它无法读取文件。非常感谢你
答案 0 :(得分:1)
这不是我自己的代码,我很久以前就找到了它。这里的链接(http://snipplr.com/view/35935/)可能不是原始来源,所以我也在发布代码。
所以这段代码将运行一个命令,并将所有输出转换为CString,WaitForSingleObject( pi.hProcess, INFINITE );
将使您的主进程挂起,直到子进程完成。
// 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;
}