通过管道读取控制台程序输出,在ReadFile处,程序停止.相关代码如下: #define BUFFER_SIZE 4096
CHAR lpszBuffer[BUFFER_SIZE+1]={0};//读取控制台信息的缓冲区        //创建匿名管道 
SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
if (!CreatePipe(&hRead,&hWrite,&sa,0)) 
{
MessageBox("创建管道失败");
return;

STARTUPINFO si;
PROCESS_INFORMATION pi;  //返回值
ZeroMemory(&si,sizeof(STARTUPINFO));
//GetStartupInfo(&si); 
si.cb = sizeof(STARTUPINFO);
//si.dwFlags =  STARTF_USESTDHANDLES;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);//标准错误管道
si.hStdOutput = hWrite;//所创建进程的输出管道
si.hStdInput =  hRead;//所创建进程的输入管道 
//si.wShowWindow = SW_HIDE;//隐藏控制台

if (!CreateProcess("C:\\MYTEST.EXE",
           NULL ,
                   NULL,
   NULL,
   TRUE,
   0,
   NULL,
   NULL,
   &si,
     &pi)) 
{

CloseHandle(hRead); //读管道
CloseHandle(hWrite);//写管道
        hRead  = NULL;//防止2次关闭
hWrite = NULL; MessageBox("创建进程失败");
return;
}
else//释放内核对象
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
while(1)
{
if (!::ReadFile(hRead, lpszBuffer, BUFFER_SIZE,
&nBytesRead, NULL) || !nBytesRead)

{
if (::GetLastError() == ERROR_BROKEN_PIPE)
break; // pipe done - normal exit path.
else
ASSERT(FALSE); // Something bad happened.
}
if (nBytesRead)
{
// Virtual function to notify derived class that
// characters are writted to stdout.
lpszBuffer[nBytesRead] = '\0';
//发送界面显示读取的内容的消息
PostMessage(WM_PIPE_DISPPLAY,nBytesRead,0);
}
Sleep(200);
} 执行到 ReadFile的地方,程序没有了反应,这是为什么?

解决方案 »

  1.   

    si.hStdOutput = hWrite;//所创建进程的输出管道 
    si.hStdInput =  hRead;//所创建进程的输入管道 
    读和写对调一下。
      

  2.   

    读和写对调一下。 问题依旧.上面的代码在GUI程序中测试正确.在控制台程序中,不正确.这是为什么?
      

  3.   

    你每次读完 管道总的数据就会请空,当你while循环的时候管道中没有数据的时候酒会发生阻塞.
    你可以用peeknamedpipe()在每次读前判断下管道中是不是用数据,有数据再readfilewhile(TURE)
    {
     peeknamedpipe();//可以得出管道中的有效数据数量
    //省略
    }
      

  4.   

    你可以看看peeknamedpipe 他是可以用于命名管道和匿名管道的 它只是复制不进行清除
      

  5.   

    按照上面朋友的思路,将代码修改如下:
    管道内始终无法读到数据,用开进程的方式,调用ping.exe文件,读管道内就应该数据了.这样理解对吗?相应程序的代码如下:#define BUFFER_SIZE 4096 
    CHAR lpszBuffer[BUFFER_SIZE+1]={0};//读取控制台信息的缓冲区 
    //创建匿名管道 
    SECURITY_ATTRIBUTES sa;
    sa.bInheritHandle=TRUE;
    sa.lpSecurityDescriptor=NULL;
    sa.nLength=sizeof(SECURITY_ATTRIBUTES);
    if(!CreatePipe(&hRead,&hWrite,&sa,0))
    {
    MessageBox("创建匿名管道失败!","提示",MB_ICONINFORMATION);
    return;
    } STARTUPINFO si;
    PROCESS_INFORMATION pi;  //返回值
    //ZeroMemory(&si,sizeof(STARTUPINFO));
    GetStartupInfo(&si); 
    si.cb = sizeof(STARTUPINFO);
    //si.dwFlags =  STARTF_USESTDHANDLES;
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    si.hStdError = GetStdHandle(STD_ERROR_HANDLE);//标准错误管道
    si.hStdOutput = hWrite;//所创建进程的输出管道
    si.hStdInput =  hRead;//所创建进程的输入管道 
    //si.wShowWindow = SW_HIDE;//隐藏控制台
    si.wShowWindow = SW_SHOW; if (!CreateProcess("C:\\WINDOWS\\system32\\ping.exe",
                   NULL,
                       NULL,
       NULL,
       TRUE,
       0,
       NULL,
       NULL,
       &si,
         &pi)) 
    {

    CloseHandle(hRead); //读管道
    CloseHandle(hWrite);//写管道
            hRead  = NULL;//防止2次关闭
    hWrite = NULL; MessageBox("创建进程失败","提示",MB_ICONINFORMATION);
    return;
    }
    else//释放内核对象
    {
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    }        Sleep(500);
         DWORD nBytesRead;//实际读取的字节数

    while(1)//由于管道内没有数据,因此发生的死循环
    {
            //确定管道内是否有数据   
    if(!PeekNamedPipe(hRead,lpszBuffer,1,&nBytesRead,NULL,0)) 
    {
    if(nBytesRead)
    {
    if (!::ReadFile(hRead, lpszBuffer, BUFFER_SIZE,
    &nBytesRead, NULL) || !nBytesRead)
    {
    if (::GetLastError() == ERROR_BROKEN_PIPE)
    break;                                 else
    ASSERT(FALSE); // Something bad happened.
    }
    else
    {
    // Virtual function to notify derived class that
    // characters are writted to stdout.
    lpszBuffer[nBytesRead] = '\0';
    //发送界面显示读取的内容的消息
    PostMessage(WM_PIPE_DISPPLAY,nBytesRead,0);
    }
    break;
    }
    }
    Sleep(200);
    } //等待进程结束
    WaitForSingleObject(pi.hProcess,INFINITE);管道内为什么没有数据呢?
      

  6.   

    if(!PeekNamedPipe(hRead,lpszBuffer,1,&nBytesRead,NULL,0)) 
    这举代码出了,问题.判断用的不对.谢谢pangqi022