因为工作的要求,要做一个格式化程序,找了很多资料,发现管道的代码都差不多,一气之下,自己写了个
//pipe attribute
SECURITY_ATTRIBUTES sa;
sa.bInheritHandle = TRUE;
sa.nLength = sizeof(SECURITY_ATTRIBUTES); //使用系统默认的安全描述符
sa.lpSecurityDescriptor = NULL; //一定要为TRUE,不然句柄不能被继承
//Read Info from process
//SubProcess->MainProcess
//SubProcess write something to output.
// |
//MainProcess read something from input.
//so
//SubPorcess Redirect STDOUT to WritePipe handler
//hWrite0 can only be used by SubProcess.
//so push hWrite0 as a parameter of CreateProcess
//and after CreateProcess,should Close hWrite0.
HANDLE hRead0,hWrite0;
HANDLE hReadPipeNonInheritable;
//get STDOUT handler
HANDLE hStdout =::GetStdHandle(STD_OUTPUT_HANDLE);
if( hStdout == INVALID_HANDLE_VALUE )

...{
::MessageBox(NULL, TEXT("Can not retrieve stdout"), TEXT("Error"), MB_OK);
return;
}
if(!CreatePipe(&hRead0,&hWrite0,&sa,0)) //创建匿名管道

...{
return;
}
//redirect to STDOUT to WritePipe handler.
if( !::SetStdHandle(STD_OUTPUT_HANDLE, hWrite0) )

...{
::MessageBox(NULL, TEXT("Can not redirect stdout"), TEXT("Error"), MB_OK);
::CloseHandle( hRead0);
::CloseHandle( hWrite0);
return;
}
//duplicatehandle get hReadPipeNonInheritable ,which is inheritable.
if( ::DuplicateHandle(
GetCurrentProcess(), hRead0,
GetCurrentProcess(), &hReadPipeNonInheritable,
0, FALSE, DUPLICATE_SAME_ACCESS))

...{
::CloseHandle( hRead0);
hRead0 = NULL;
}
else

...{
::MessageBox(NULL, TEXT("Can not duplicate handle"), TEXT("Error"), MB_OK);
::CloseHandle( hRead0 );
::CloseHandle( hWrite0 );
::SetStdHandle(STD_OUTPUT_HANDLE, hStdout);
return ;
}

//write info to SubProcess
//MainProcess->SubProcess
// MainProcess write something to output.----||
// ||PIPE
//SubProcess read something from input. <---||
//so
//SubPorcess Redirect STDINPUT to ReadPipe handler
//hRead1 can only be used by SubProcess.
//so push hRead1 as a parameter of CreateProcess
//and after CreateProcess,should Close hRead1.
HANDLE hRead1,hWrite1;
HANDLE hWritePipeNonInheritable;
HANDLE hStdin =::GetStdHandle( STD_INPUT_HANDLE );
if( hStdin == INVALID_HANDLE_VALUE )

...{
::MessageBox(NULL, TEXT("Can not retrieve stdin"), TEXT("Error"), MB_OK);
return;
}
if(!CreatePipe(&hRead1,&hWrite1,&sa,0)) //创建匿名管道

...{
return;
}
if( !::SetStdHandle(STD_INPUT_HANDLE, hRead1) )

...{
::MessageBox(NULL,TEXT("Can not redirect stdin"), TEXT("Error"), MB_OK);
::CloseHandle( hRead1);
::CloseHandle( hWrite1);
return;
}
if( ::DuplicateHandle(
GetCurrentProcess(), hWrite1,
GetCurrentProcess(), &hWritePipeNonInheritable,
0, FALSE, DUPLICATE_SAME_ACCESS ) )

...{
::CloseHandle(hWrite1);
hWrite1 = NULL;
}
else

...{
::MessageBox(NULL, TEXT("Can not duplicate handle"), TEXT("Error"), MB_OK);
::CloseHandle( hRead1 );
::CloseHandle( hWrite1 );
::SetStdHandle(STD_INPUT_HANDLE, hStdin);
return ;
}
STARTUPINFO si; // 启动信息
PROCESS_INFORMATION pi; // 进程信息
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si); //取得当前进程的StartupInfo,并根据当前进程进行修改
si.hStdError = hWrite0; //错误输出 表示为子进程的输出
si.hStdOutput = hWrite0; //标准输出
si.hStdInput = hRead1;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
//创建子进程
if(!CreateProcess(NULL,"cmd.exe",NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))

...{

return /**//*FALSE*/;
}
CloseHandle(hWrite0); //关闭主进程的输出。
CloseHandle(hRead1);
// restore stdin
if( !::SetStdHandle(STD_INPUT_HANDLE, hStdin) )

...{
::MessageBox(NULL, TEXT("Can not restore stdin"), TEXT("Error"), MB_OK);
::CloseHandle( hWritePipeNonInheritable );
return ;
}
if( !::SetStdHandle(STD_OUTPUT_HANDLE, hStdout) )

...{
::MessageBox(NULL, TEXT("Can not restore stdout"), TEXT("Error"), MB_OK);
::CloseHandle( hReadPipeNonInheritable );
return ;
}

char CMD[512]="ping www.163.com ";

char buffer[4096]=...{0};
DWORD bytesRead;
WriteFile(hWritePipeNonInheritable,CMD,strlen(CMD),&bytesRead,NULL);
CString tmp;
while (true)

...{
if(ReadFile(hReadPipeNonInheritable,buffer,4095,&bytesRead,NULL)==NULL)

...{
break;
}
TRACE(buffer);
tmp+=buffer;
m_edit1.SetWindowText(tmp);
m_edit1.LineScroll(m_edit1.GetLineCount());
Sleep(200);
}