首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

关于管道向命令行输入输出失败有关问题

2012-11-09 
关于管道向命令行输入输出失败问题情景:我要实现的目的是通过我的程序,取得本地的CMD的命令输入入口和输出

关于管道向命令行输入输出失败问题

情景:我要实现的目的是通过我的程序,取得本地的CMD的命令输入入口和输出。即我输入任何CMD命令,能通过CMD窗口(隐藏的)来执行,并把结果输出到我指定的地方。

实现方法:主线程M先创建两个子线程A和B。        

           线程A负责产生输入管道PA,并把从其他方式送过来的命令写到这个管道PA(通过在创建CMD进程时指定startinfo.hStdInput来指定监听的输入);        

           线程B负责产生输出管道PB,并监听管道PB数据写到指定目的地。        

           主线程等A,B线程产生好管道以后,创建CMD的进程,在参数中把startinfo.hStdInput设置为读PA数据,startinfo.hStdOutput设置为输出到PB。情景如下图:

 

           问题描述,线程A正常运行,线程B也正常运行,主线程创建CMD进程成功,其设置输入输入参数也是在管道产生之后的正确参数。问题是:我可以正常在线程A把命令数据(如dir)写到管道PA中(WriteFile返回TRUE),但无法在线程B中监听到处理结果。

关于管道向命令行输入输出失败有关问题

           我觉得上图两个问号就是可能出现问题的地方。但目前没有办法确认,下面附上代码。请问有哪位处理过相关问题的,麻烦指导一下。谢谢!

 

#include <stdio.h>#include <string.h>#include <winsock2.h>HANDLE hReadPipe, hWritePipe, hWriteFile, hReadFile;u_char varRead,varWrite;DWORD WINAPI ThreadFuncRead(LPVOID lpParam){    //声明一个安全属性结构变量    SECURITY_ATTRIBUTES pipeattr;    DWORD nByteToWrite, nByteWritten;    char recv_buff[1024];int nRetCode;//对pipeattr的各个成员进行赋值memset(recv_buff,0,sizeof(recv_buff));    pipeattr.nLength = sizeof(SECURITY_ATTRIBUTES);    pipeattr.lpSecurityDescriptor = NULL;pipeattr.bInheritHandle = TRUE;//创建一个匿名管道,并使用上面的安全属性结构变量pipeattr为管道的安全属性//其中hReadPipe是用来从管道中读取数据的管道句柄//hWriteFile是向管道写入数据的管道句柄    nRetCode = CreatePipe(&hReadPipe,&hWriteFile,&pipeattr,0);    //判断管道是否创建成功    if (nRetCode == 0)    {       printf ("CreatePipe readpipe Error!\n");        exit(-1);}//如果管道创建成功,就将varRead赋值为1    varRead = 1;//得到当前进程的路径,当有用户连接上时就会显示出来TCHAR    curDirBuff[256];memset(curDirBuff,0,sizeof(curDirBuff));DWORD   nDirLength=0;nDirLength = GetCurrentDirectory(256,curDirBuff);curDirBuff[nDirLength]='>';nRetCode=WriteFile(hWriteFile,curDirBuff,nDirLength+1,&nDirLength,NULL);//使用一个无限循环,来从客户端接收数据,并写入管道    while(true)    {        Sleep(250);        //从客户端接收数据,数据写入缓冲区recv_buff中memset(recv_buff,'\0',1024);memcpy(recv_buff,"dir",3);nByteToWrite = strlen(recv_buff);        //使用WriteFile向句柄hWriteFile中写入数据,这个管道中的数据可以通过        //hReadFile管道句柄读取,而hReadFile是全局变量,则在程序中的任何地方        //都可以访问到        nRetCode = WriteFile(hWriteFile,recv_buff,nByteToWrite,&nByteWritten,NULL);    }    return 0;}DWORD WINAPI ThreadFuncWrite( LPVOID lpParam ){    //同样是先来声明一个安全属性变量pipeattr    SECURITY_ATTRIBUTES pipeattr;    DWORD len;    int nRetCode;    unsigned long nCount;    unsigned long nAvail;    char send_buff[25000];    ZeroMemory(send_buff, 25000);    //对安全属性变量赋初值    pipeattr.nLength = sizeof(SECURITY_ATTRIBUTES);    pipeattr.lpSecurityDescriptor = NULL;    pipeattr.bInheritHandle = TRUE;    //创建另外一个匿名管道,其使用的参数与上面一个线程函数处相同    nRetCode = CreatePipe(&hReadFile,&hWritePipe,&pipeattr,0);    //如果管道创建失败,就返回    if (nRetCode == 0)    {        printf ("CreatePipe writepipe Error!\n");        exit(-1);}//管道创建成功,将varWrite赋值为1varWrite = 1;//进入一个无限循环,每隔250ms就尝试从上面的这个匿名管道中读取数据,如果//管道中存在数据,ReadFile()函数通过hReadFile就可以读到数据,而且当且仅//当读到了数据,服务端才会向客户端发送数据。    while (true)    {        Sleep(250);        //尝试从hReadFile中读取数据,数据长度放入len        ReadFile(hReadFile,send_buff,25000,&len,NULL);printf("%s",send_buff);    }    return 0;}int _tmain(int argc, _TCHAR* argv[]){varRead = 0;varWrite = 0;DWORD dwThreadRead;HANDLE hThreadFuncRead = 0;if((hThreadFuncRead = CreateThread(NULL,0,ThreadFuncRead,NULL,0,&dwThreadRead)) == NULL){printf("create ThreadFuncRead error!\n");return 0;}if(CreateThread(NULL,0,ThreadFuncWrite,NULL,0,&dwThreadRead) == NULL){printf("create ThreadFuncWrite Error!\n");return 0;}do{Sleep(250);}while((!varRead || !varWrite));PROCESS_INFORMATION processinfo;STARTUPINFO startinfo;GetStartupInfo(&startinfo);startinfo.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;startinfo.lpDesktop = NULL;startinfo.hStdInput = hReadPipe;startinfo.hStdOutput = hWritePipe;startinfo.hStdError = hWritePipe;startinfo.wShowWindow = SW_SHOWNORMAL;TCHAR DirSys[256];::GetSystemDirectory(DirSys,256);wcscat(DirSys,_T("\\cmd.exe"));if(!CreateProcess(DirSys,NULL,NULL,NULL,TRUE,0,NULL,NULL,&startinfo,&processinfo)){printf("CreateProcess Error!\n");return 0;}WaitForSingleObject(hThreadFuncRead,INFINITE);}


 

1楼eagleatustb昨天 10:41
问题找到了,是因为输入命令没有加回车键表示结束输入;n50. memset(recv_buff,'\0',1024); n51. memcpy(recv_buff,"dir",3); n这里需要在dir后面加上回车

热点排行