由于匿名管道只能是单向的,因此要建立双向通信必须建立2个管道。
父程序代码:
view plaincopy to clipboardprint?
int main()
{
//定义四个句炳保留两个管道的信息
HANDLE hReadPipe1, hWritePipe1, hReadPipe2, hWritePipe2;
SECURITY_ATTRIBUTES sat;
STARTUPINFO startupinfo;
PROCESS_INFORMATION pinfo;
BYTE buffer[1024];
DWORD byteRead, byteWrite;
string rString;
string m_Host= "Client.exe";
sat.nLength=sizeof(SECURITY_ATTRIBUTES);
sat.bInheritHandle=true;
sat.lpSecurityDescriptor=NULL;
//创建管道,它用来做子进程的输出
if(!CreatePipe(&hReadPipe1, &hWritePipe1, &sat, NULL))
{
cout<<("Create Pipe Error!")<<endl;
return 1;
}
//创建管道,它用来做子进程的输入
if(!CreatePipe(&hReadPipe2, &hWritePipe2, &sat, NULL))
{
cout<<"Create Pipe Error!"<<endl;
return 1;
}
startupinfo.cb=sizeof(STARTUPINFO);
//用GetStartupInfo获得当前进程的参数,否则STARTUPINFO参数太多,会让人抓狂
GetStartupInfo(&startupinfo);
startupinfo.hStdInput = hReadPipe2;
startupinfo.hStdError=hWritePipe1;
startupinfo.hStdOutput=hWritePipe1;
//要有STARTF_USESTDHANDLES,否则hStdInput, hStdOutput, hStdError无效
startupinfo.dwFlags=STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
startupinfo.wShowWindow=SW_HIDE;
if(!CreateProcess(NULL, (char*)m_Host.c_str(), NULL, NULL, TRUE, NULL, NULL, NULL, &startupinfo, &pinfo))
{
cout<<("create process error!")<<endl;
return 1;
}
RtlZeroMemory(buffer,1024);
//进程的输出重定向到hWritePipe1,所以从hReadPipe1读取
// 在从管道中读取到数据前父进程将发生阻塞
if (ReadFile(hReadPipe1,buffer,1023,&byteRead,NULL))
{
cout<<buffer;
}
string csWrite = "ping www.sina.com.cn\r\n";
//进程的输入重定向到hReadPipe2,所以从hWritePipe2写入
// 向管道中写数据不会发生阻塞,此循环会一直执行下去。
while (WriteFile(hWritePipe2, (LPCVOID)csWrite.c_str(), csWrite.length() + 1, &byteWrite, NULL))
{
cout << "write " << byteWrite << endl;
}
CloseHandle(hReadPipe1);
CloseHandle(hReadPipe2);
CloseHandle(hWritePipe1);
CloseHandle(hWritePipe2);
return 0;
}
int main()
{
//定义四个句炳保留两个管道的信息
HANDLE hReadPipe1, hWritePipe1, hReadPipe2, hWritePipe2;
SECURITY_ATTRIBUTES sat;
STARTUPINFO startupinfo;
PROCESS_INFORMATION pinfo;
BYTE buffer[1024];
DWORD byteRead, byteWrite;
string rString;
string m_Host= "Client.exe";
sat.nLength=sizeof(SECURITY_ATTRIBUTES);
sat.bInheritHandle=true;
sat.lpSecurityDescriptor=NULL;
//创建管道,它用来做子进程的输出
if(!CreatePipe(&hReadPipe1, &hWritePipe1, &sat, NULL))
{
cout<<("Create Pipe Error!")<<endl;
return 1;
}
//创建管道,它用来做子进程的输入
if(!CreatePipe(&hReadPipe2, &hWritePipe2, &sat, NULL))
{
cout<<"Create Pipe Error!"<<endl;
return 1;
}
startupinfo.cb=sizeof(STARTUPINFO);
//用GetStartupInfo获得当前进程的参数,否则STARTUPINFO参数太多,会让人抓狂
GetStartupInfo(&startupinfo);
startupinfo.hStdInput = hReadPipe2;
startupinfo.hStdError=hWritePipe1;
startupinfo.hStdOutput=hWritePipe1;
//要有STARTF_USESTDHANDLES,否则hStdInput, hStdOutput, hStdError无效
startupinfo.dwFlags=STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
startupinfo.wShowWindow=SW_HIDE;
if(!CreateProcess(NULL, (char*)m_Host.c_str(), NULL, NULL, TRUE, NULL, NULL, NULL, &startupinfo, &pinfo))
{
cout<<("create process error!")<<endl;
return 1;
}
RtlZeroMemory(buffer,1024);
//进程的输出重定向到hWritePipe1,所以从hReadPipe1读取
// 在从管道中读取到数据前父进程将发生阻塞
if (ReadFile(hReadPipe1,buffer,1023,&byteRead,NULL))
{
cout<<buffer;
}
string csWrite = "ping www.sina.com.cn\r\n";
//进程的输入重定向到hReadPipe2,所以从hWritePipe2写入
// 向管道中写数据不会发生阻塞,此循环会一直执行下去。
while (WriteFile(hWritePipe2, (LPCVOID)csWrite.c_str(), csWrite.length() + 1, &byteWrite, NULL))
{
cout << "write " << byteWrite << endl;
}
CloseHandle(hReadPipe1);
CloseHandle(hReadPipe2);
CloseHandle(hWritePipe1);
CloseHandle(hWritePipe2);
return 0;
}
子进程代码:
view plaincopy to clipboardprint?
int main(int argc, char* argv[])
{
hRead = GetStdHandle(STD_INPUT_HANDLE);
hWrite = GetStdHandle(STD_OUTPUT_HANDLE);
char s[] = "Hello, I am child process\n";
DWORD dwWrite;
if (!WriteFile(hWrite, s, strlen(s) + 1, &dwWrite, NULL))
{
out << "Write to pipe failed!" << endl;
return -1;
}
char buf[100];
DWORD dwRead;
if(!ReadFile(hRead, buf, 100, &dwRead, NULL))
{
out << "Read from pipe failed!" << endl;
return -1;
}
}