来看一例子
#include
#include
#define BUFSIZE 4096 HANDLE hfInRd, hfInWr, hfoutWrDup, hfOutRd, hfOutWr, hChildStdoutRdDup, hStdout;
DWORD main(int argc, char *argv[])
{
SECURITY_ATTRIBUTES saAttr;
BOOL fSuccess; // 设置一个有继承属性的安全属性,用于创建管道.
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL; // 创建一个有继承属性的管道
CreatePipe(&hfOutRd, &hSInWr, &saAttr, 0); //给父进程读的// 将管道的读句柄拷贝一份到hfRdDup
DuplicateHandle(GetCurrentProcess(), hfOutRd,
GetCurrentProcess(), &hfOutRdDup , 0,
FALSE, // 非继承
DUPLICATE_SAME_ACCESS); //关闭读管道,注意,虽然它关闭了,但是还有一个可读管道保存在hfRdDup中
CloseHandle(hfRd);
CreatePipe(&hSOutRd, &hfInWr, &saAttr, 0)); //给父进程写的
DuplicateHandle(GetCurrentProcess(), hfInWr,
GetCurrentProcess(), &hfInWrDup, 0,
FALSE, // 非继承
DUPLICATE_SAME_ACCESS);
CloseHandle(hfInWr); // 创建进程
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
BOOL bFuncRetn = FALSE;
ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = hSInWr;
siStartInfo.hStdOutput = hSInWr;
siStartInfo.hStdInput = hSOutRd;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES; //子进程的hStdOutput被赋予了hSInWr, 而这个写端对应的读端是hfOutRd,所以父进程可以 //从hfOutRdDup上读到子进程的标准输出; //而子程序的hStdInput被赋予了hfInRd, 这个端对应的写端是hfInWr //这表示,父进程可以通过hfInWrUp把数据写到子进程的标准输入上 //这里主要以父进程为目标来说明的,因为子进程通常是别人写的程序。所以创建了两个管道,分别用于输入到输出(相对于子进程),否则,完全可以用一个管道,由两个进程协商IO的顺序
CreateProcess(NULL, "child", // command line
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProcInfo.hThread);
WriteToPipe(hfInWrDup); // 。。。
ReadFromPipe(hfOutRdDup); //。。。
return 0;
}
#include
#include
int main()
{
int i;
for(i=0;i<100;++i)
{
printf("\nThis is speaker beep number %d... \n\7", i+1);
}
return 0;
}
// BeepFilter.Cpp
/* Compile options needed: none
Execute as:BeepFilter.exe Beeper.exe
*/
#include
#include
#include
#include
#include
#include
#include
#define OUT_BUFF_SIZE 512
#define READ_HANDLE 0
#define WRITE_HANDLE1
#define BEEP_CHAR7
char szBuffer[OUT_BUFF_SIZE];
int Filter(char* szBuff, ULONG nSize, int nChar)
{
char* szPos =szBuff + nSize -1;
char* szEnd =szPos;
int nRet =nSize;
while (szPos> szBuff)
{
if (*szPos ==nChar)
{
memmove(szPos, szPos+1, szEnd - szPos);
--nRet;
}
--szPos;
}
return nRet;
}
int main(int argc, char** argv)
{
int nExitCode =STILL_ACTIVE;
if (argc >=2)
{
HANDLEhProcess;
int hStdOut;
inthStdOutPipe[2];
// Create thepipe
if(_pipe(hStdOutPipe, 512, O_BINARY | O_NOINHERIT) == -1)
return 1;
// Duplicatestdout handle (next line will close original)
hStdOut =_dup(_fileno(stdout));
// Duplicate write end of pipe to stdouthandle
if(_dup2(hStdOutPipe[WRITE_HANDLE], _fileno(stdout)) != 0)
return 2;
// Closeoriginal write end of pipe
close(hStdOutPipe[WRITE_HANDLE]);
// Spawnprocess
hProcess =(HANDLE)spawnvp(P_NOWAIT, argv[1],
(const char*const*)&argv[1]);
// Duplicatecopy of original stdout back into stdout
if(_dup2(hStdOut, _fileno(stdout)) != 0)
return 3;
// Closeduplicate copy of original stdout
close(hStdOut);
if(hProcess)
{
intnOutRead;
while (nExitCode == STILL_ACTIVE)
{
nOutRead = read(hStdOutPipe[READ_HANDLE],
szBuffer, OUT_BUFF_SIZE);
if(nOutRead)
{
nOutRead = Filter(szBuffer, nOutRead, BEEP_CHAR);
fwrite(szBuffer, 1, nOutRead, stdout);
}
if(!GetExitCodeProcess(hProcess,(unsigned long*)&nExitCode))
return 4;
}
}
}
printf("\nPress \'ENTER\' key to continue... ");
getchar();
returnnExitCode;
}
#include
#include
void main( void )
{
char psBuffer[128];
FILE *chkdsk;
/* Run DIRso that it writes its output to a pipe. Open this
* pipe withread text attribute so that we can read it
* like atext file.
*/
if( (chkdsk =_popen( "dir *.c /on /p", "rt" )) == NULL )
exit( 1 );
/* Read pipeuntil end of file. End of file indicates that
* CHKDSK closedits standard out (probably meaning it
*terminated).
*/
while( !feof(chkdsk ) )
{
if( fgets(psBuffer, 128, chkdsk ) != NULL )
printf(psBuffer );
}
/* Close pipeand print return value of CHKDSK. */
printf("\nProcess returned %d\n", _pclose( chkdsk ) );
}