BOOL CShellView::CreateShellRedirect() { SECURITY_ATTRIBUTES saAttr; BOOL fSuccess;// Set the bInheritHandle flag so pipe handles are inherited. saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL;// The steps for redirecting child process's STDOUT: // 1. Save current STDOUT, to be restored later. // 2. Create anonymous pipe to be STDOUT for child process. // 3. Set STDOUT of the parent process to be write handle to // the pipe, so it is inherited by the child process. // 4. Create a noninheritable duplicate of the read handle and // close the inheritable read handle.// Save the handle to the current STDOUT. hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);// Create a pipe for the child process's STDOUT. if( !CreatePipe( &hChildStdoutRd, &hChildStdoutWr, &saAttr, 0) ) { TRACE0( _T("Stdout pipe creation failed\n") ); return FALSE; }// Set a write handle to the pipe to be STDOUT. if( !SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr) ) { TRACE0( _T("Redirecting STDOUT failed\n") ); return FALSE; }// Create noninheritable read handle and close the inheritable read handle. fSuccess = DuplicateHandle( GetCurrentProcess(), hChildStdoutRd, GetCurrentProcess(), &hChildStdoutRdDup , 0, FALSE, DUPLICATE_SAME_ACCESS ); if( !fSuccess ) { TRACE0( _T("DuplicateHandle failed\n") ); return FALSE; } CloseHandle( hChildStdoutRd );// The steps for redirecting child process's STDIN: // 1. Save current STDIN, to be restored later. // 2. Create anonymous pipe to be STDIN for child process. // 3. Set STDIN of the parent to be the read handle to the // pipe, so it is inherited by the child process. // 4. Create a noninheritable duplicate of the write handle, // and close the inheritable write handle.// Save the handle to the current STDIN. hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);// Create a pipe for the child process's STDIN. if( !CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0) ) { TRACE0( _T("Stdin pipe creation failed\n") ); return FALSE; } // Set a read handle to the pipe to be STDIN. if( !SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd) ) { TRACE0( _T("Redirecting Stdin failed\n") ); return FALSE; } // Duplicate the write handle to the pipe so it is not inherited. fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr, GetCurrentProcess(), &hChildStdinWrDup, 0, FALSE, // not inherited DUPLICATE_SAME_ACCESS ); if( !fSuccess ) { TRACE0( _T("DuplicateHandle failed\n") ); return FALSE; } CloseHandle(hChildStdinWr);// Now create the child process. if( !CreateChildProcess(dwProcessId) ) { TRACE0( _T("CreateChildProcess failed\n") ); return FALSE; } // After process creation, restore the saved STDIN and STDOUT. if( !SetStdHandle(STD_INPUT_HANDLE, hSaveStdin) ) { TRACE0( _T("Re-redirecting Stdin failed\n") ); return FALSE; } if( !SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout) ) { TRACE0( _T("Re-redirecting Stdout failed\n") ); return FALSE; } m_pReadThread = fxBeginThread( (AFX_THREADPROC)ReadPipeThreadProc,(LPVOID)this ); if( !m_pReadThread ) { TRACE0( _T("Cannot start read-redirect thread!\n") ); return FALSE; } return TRUE; }BOOL CShellView::CreateChildProcess(DWORD& dwProcessId) { PROCESS_INFORMATION piProcInfo; STARTUPINFO siStartInfo;// Set up members of STARTUPINFO structure. ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); siStartInfo.cb = sizeof(STARTUPINFO); ///////////////////////////////////////// /* Note here the dwFlags should be STARTF_USESTDHANDLES, which is descripted in WIN32 API document, but this was omitted in MSDN sample */ siStartInfo.dwFlags = STARTF_USESTDHANDLES; siStartInfo.hStdInput = hChildStdinRd; siStartInfo.hStdOutput = hChildStdoutWr; siStartInfo.hStdError = hChildStdoutWr;/////////////////////////////////////////////////// TCHAR shellCmd[_MAX_PATH]; if( !GetEnvironmentVariable(_T("ComSpec"), shellCmd, _MAX_PATH) ) return FALSE; #ifdef _UNICODE _tcscat( shellCmd, _T(" /U") ); #else _tcscat( shellCmd, _T(" /A") ); #endif // Create the child process. BOOL ret = CreateProcess( NULL, shellCmd, // applicatin name NULL, // process security attributes NULL, // primary thread security attributes TRUE, // handles are inherited DETACHED_PROCESS, // creation flags NULL, // use parent's environment NULL, // use parent's current directory &siStartInfo, // STARTUPINFO pointer &piProcInfo); // receives PROCESS_INFORMATION if( ret ) dwProcessId = piProcInfo.dwProcessId; return ret; }使用管道!可以解决你的问题。
你可以参考这个
http://www.codeguru.com/misc/RedirectOutputToPipe.shtml
{
SECURITY_ATTRIBUTES saAttr;
BOOL fSuccess;// Set the bInheritHandle flag so pipe handles are inherited.
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;// The steps for redirecting child process's STDOUT:
// 1. Save current STDOUT, to be restored later.
// 2. Create anonymous pipe to be STDOUT for child process.
// 3. Set STDOUT of the parent process to be write handle to
// the pipe, so it is inherited by the child process.
// 4. Create a noninheritable duplicate of the read handle and
// close the inheritable read handle.// Save the handle to the current STDOUT.
hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);// Create a pipe for the child process's STDOUT.
if( !CreatePipe( &hChildStdoutRd, &hChildStdoutWr, &saAttr, 0) )
{
TRACE0( _T("Stdout pipe creation failed\n") );
return FALSE;
}// Set a write handle to the pipe to be STDOUT.
if( !SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr) )
{
TRACE0( _T("Redirecting STDOUT failed\n") );
return FALSE;
}// Create noninheritable read handle and close the inheritable read handle.
fSuccess = DuplicateHandle( GetCurrentProcess(), hChildStdoutRd,
GetCurrentProcess(), &hChildStdoutRdDup ,
0, FALSE,
DUPLICATE_SAME_ACCESS );
if( !fSuccess )
{
TRACE0( _T("DuplicateHandle failed\n") );
return FALSE;
}
CloseHandle( hChildStdoutRd );// The steps for redirecting child process's STDIN:
// 1. Save current STDIN, to be restored later.
// 2. Create anonymous pipe to be STDIN for child process.
// 3. Set STDIN of the parent to be the read handle to the
// pipe, so it is inherited by the child process.
// 4. Create a noninheritable duplicate of the write handle,
// and close the inheritable write handle.// Save the handle to the current STDIN.
hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);// Create a pipe for the child process's STDIN.
if( !CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0) )
{
TRACE0( _T("Stdin pipe creation failed\n") );
return FALSE;
}
// Set a read handle to the pipe to be STDIN.
if( !SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd) )
{
TRACE0( _T("Redirecting Stdin failed\n") );
return FALSE;
}
// Duplicate the write handle to the pipe so it is not inherited.
fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
GetCurrentProcess(), &hChildStdinWrDup,
0, FALSE, // not inherited
DUPLICATE_SAME_ACCESS );
if( !fSuccess )
{
TRACE0( _T("DuplicateHandle failed\n") );
return FALSE;
}
CloseHandle(hChildStdinWr);// Now create the child process.
if( !CreateChildProcess(dwProcessId) )
{
TRACE0( _T("CreateChildProcess failed\n") );
return FALSE;
}
// After process creation, restore the saved STDIN and STDOUT.
if( !SetStdHandle(STD_INPUT_HANDLE, hSaveStdin) )
{
TRACE0( _T("Re-redirecting Stdin failed\n") );
return FALSE;
}
if( !SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout) )
{
TRACE0( _T("Re-redirecting Stdout failed\n") );
return FALSE;
}
m_pReadThread =
fxBeginThread( (AFX_THREADPROC)ReadPipeThreadProc,(LPVOID)this );
if( !m_pReadThread )
{
TRACE0( _T("Cannot start read-redirect thread!\n") );
return FALSE;
}
return TRUE;
}BOOL CShellView::CreateChildProcess(DWORD& dwProcessId)
{
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;// Set up members of STARTUPINFO structure.
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);
/////////////////////////////////////////
/*
Note here the
dwFlags should be STARTF_USESTDHANDLES, which is descripted in WIN32 API
document, but this was
omitted in MSDN sample
*/
siStartInfo.dwFlags = STARTF_USESTDHANDLES;
siStartInfo.hStdInput = hChildStdinRd;
siStartInfo.hStdOutput = hChildStdoutWr;
siStartInfo.hStdError = hChildStdoutWr;///////////////////////////////////////////////////
TCHAR shellCmd[_MAX_PATH];
if( !GetEnvironmentVariable(_T("ComSpec"), shellCmd, _MAX_PATH) )
return FALSE;
#ifdef _UNICODE
_tcscat( shellCmd, _T(" /U") );
#else
_tcscat( shellCmd, _T(" /A") );
#endif
// Create the child process.
BOOL ret = CreateProcess( NULL,
shellCmd, // applicatin name
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
DETACHED_PROCESS, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
if( ret )
dwProcessId = piProcInfo.dwProcessId;
return ret;
}使用管道!可以解决你的问题。
无法获取所有的窗口内容!