IO重定向

BOOL 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 = AfxBeginThread( (AFX_THREADPROC)ReadPipeThreadProc,(LPVOID)this );
if( !m_pReadThread )
{
  TRACE0( _T("Cannot start read-redirect thread!/n") );
  return FALSE;
}
return TRUE;
}

BOOL CreateChildProcess(DWORD& dwProcessId)
{
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;  
// Set up members of STARTUPINFO structure.  
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);  

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;
}

UINT ReadPipeThreadProc( LPVOID pParam )
{
DWORD dwRead;
TCHAR chBuf[BUFSIZE];
CShellView* pView = (CShellView*)pParam;
TRACE0( _T("ReadPipe Thread begin run/n") );
for( ;; )    
{
  if( !ReadFile( pView->hChildStdoutRdDup, chBuf,
   BUFSIZE, &dwRead, NULL) || dwRead == 0)
   break;
  chBuf[dwRead/sizeof(TCHAR)] = _T('/0');
  pView->AddTexts( chBuf );
  pView->m_nLength = pView->GetEditCtrl().SendMessage( WM_GETTEXTLENGTH );
}
CloseHandle( pView ->hChildStdinRd);
CloseHandle( pView ->hChildStdoutWr);
CloseHandle( pView ->hChildStdinWrDup );
CloseHandle( pView ->hChildStdoutRdDup );
pView->m_pReadThread = NULL;
pView->dwProcessId = DWORD(-1);
pView->PostMessage( WM_CLOSE );
return 1;
}

注:利用两个匿名管道(一个输入,一个输出)操作子进程的IO
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值