用无名管道重定向子进程的输入输出

来源:互联网 发布:2016好听的网络歌曲 编辑:程序博客网 时间:2024/05/16 09:45


PipeServer:

// 开启管道服务器int StartPipeServer(int Size,char style,TCHAR *path){PipeElem item;SECURITY_ATTRIBUTES saAttr;STARTUPINFO si;PROCESS_INFORMATION pi;TCHAR lpszComCmdLine[] = L"UsbSpeedTestTool.exe";TCHAR lpszCmdLine[256];char strMsg[64];saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);saAttr.bInheritHandle = TRUE;saAttr.lpSecurityDescriptor = NULL;if(!CreatePipe(&item.hStdInRead,&item.hStdInWrite,&saAttr,0)){LoadStringA(NULL,IDS_CREATE_PIPE_FAILED1,strMsg,64);printf("%s %d\n",strMsg,GetLastError());return -1;} if(!CreatePipe(&item.hStdOutRead,&item.hStdOutWrite,&saAttr,0)){LoadStringA(NULL,IDS_CREATE_PIPE_FAILED2,strMsg,64);printf("%s %d\n",strMsg,GetLastError());return -1;}if(!DuplicateHandle(GetCurrentProcess(),item.hStdOutWrite,GetCurrentProcess(),&item.hStdErrWrite,0,TRUE,DUPLICATE_SAME_ACCESS)){LoadStringA(NULL,IDS_DUPLICATE_PIPE_FAILED,strMsg,64);printf("%s %d\n",strMsg,GetLastError());return -1;}item.iNum = giClientNum++;item.usbPath = path;AddPipeNode(glistPipe,item);DWORD id;HANDLE hThread =  CreateThread(NULL,0,ReadFromClientPipeThread,(LPVOID)item.iNum,0,&id);if(hThread == NULL){LoadStringA(NULL,IDS_CREATE_THREAD_FAILED,strMsg,64);printf("%s %d\n",strMsg,GetLastError());return -1;}LoadStringA(NULL,IDS_CREATE_THREAD_READPIPE,strMsg,64);printf("%s, thread id=%d\n",strMsg,id);wsprintf(lpszCmdLine,L"%s %d %c %s",lpszComCmdLine,Size,style,path);//wprintf(_T("CmdLine:%s\n"),lpszCmdLine);ZeroMemory(&si,sizeof(si));si.cb = sizeof(STARTUPINFO);si.dwFlags |= STARTF_USESTDHANDLES;si.dwFlags |= STARTF_USESHOWWINDOW;si.hStdOutput = item.hStdOutWrite;   // 子进程的stdout输出到hStdOutWritesi.hStdError  = item.hStdErrWrite;   // 子进程的stderr输出到hStdErrWritesi.hStdInput  = item.hStdInRead;hStdInRead = item.hStdInWrite;if(!CreateProcess(NULL,lpszCmdLine,NULL,NULL,TRUE,0,NULL,NULL,&si,&pi)){LoadStringA(NULL,IDS_CREATE_PROCESS_FAILED,strMsg,64);printf("%s %d\n",strMsg,GetLastError());return -1;}return 0;}
// 写入stdinBOOL WriteToPipe(char *inbuff,HANDLE hPipe){DWORD dwWritten;BOOL bSuccess = WriteFile(hPipe,inbuff,strlen(inbuff),&dwWritten,NULL);if(bSuccess) return true;else {char strMsg[32];LoadStringA(NULL,IDS_WRITEFILE_FAILED,strMsg,32);printf("%s %d\n",strMsg,GetLastError());return false;}}// 读出stdoutBOOL ReadFromPipe(char *outbuff,HANDLE hPipe){DWORD dwRead = 0;memset(outbuff,0,sizeof(outbuff));if(ReadFile(hPipe,outbuff,255,&dwRead,NULL)){return true;}else{char strMsg[32];LoadStringA(NULL,IDS_READFILE_FAILED,strMsg,32);printf("%s %d\n",strMsg,GetLastError());return false;}}// 从管道读取数据线程DWORD CALLBACK ReadFromClientPipeThread(LPVOID lpvParam){switch(giLangSel){case 1:SetThreadUILanguage(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED));break;case 2:SetThreadUILanguage(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US));break;}char strMsg[64];char strbuf[256]="";int num = (int)lpvParam;HANDLE hPipe = GetReadOutHandleByNum(glistPipe,num);if(hPipe == NULL){LoadStringA(NULL,IDS_GET_READOUT_FAILED,strMsg,64);printf("%s\n",strMsg);return 0;}char recvbuf[256]="";DWORD dwLen = 0;int iSend = 0;while(ReadFile(hPipe,recvbuf,256,&dwLen,NULL)){LoadStringA(NULL,IDS_RECV_FROM_,strMsg,64);CharCut(recvbuf);iSend = send(sockConn,recvbuf,strlen(recvbuf)+1,0);if(iSend == SOCKET_ERROR){LoadStringA(NULL,IDS_RECVFROM_PIPE_SEND_ERR,strMsg,64);printf("%s %d\n",strMsg,GetLastError());break;}if(mySubstrFind(recvbuf,"done") >= 0){printf("\n%s %d:%s\n",strMsg,num,recvbuf);int iSend = send(sockConn,"[done]",7,0);if(iSend <= 0){LoadStringA(NULL,IDS_RECVFROM_PIPE_SEND_DONE_FAILED,strMsg,64);printf("%s %d\n",strMsg,GetLastError());}break;}else{sprintf_s(strbuf,256,"%s %d:%s",strMsg,num,recvbuf);OneLineOutput(strbuf);}memset(recvbuf,'\0',sizeof(recvbuf));}LoadStringA(NULL,IDS_RECVFROM_PIPE_THREAD_QUIT,strMsg,64);printf("%s\n",strMsg);return 0;}



PipeClient:

1.只要读取stdin,和写入stdout。字符串后面加上'\n'。

2.如果管道服务器还是不能及时收到数据,用fflush(stdout);

3.管道中有数据时子进程不能退出,否则服务器收不到数据。

4.客户端退出时可以略微延时

















0 0