2013-11-02 124 views
0

我正在開發一個類似程序的遠程shell。在遠程機器上運行命令我創建一個cmd.exe進程,並將其stdin和stdout重定向到一對管道。 我使用這些管道發送命令並獲得結果。 我使用ReadFile函數從cmd.exe返回命令的輸出,但我不知道 我必須從pipe讀取的確切數據量。所以如果數據沒有準備好,讀取文件 進入阻塞模式並等待數據。從管道中讀取塊和死鎖

我使用的是MSVC++ 2010,我的操作系統是Win7。這裏是作爲一個例子我的代碼的一部分:

void CpipesDlg::OnBnClickedBtnredirstd() 
{ 
    char Cmd[]="dir *.*\r\n"; 
    char Buff[129]; 
    CString str; 
    HANDLE hStdIn_Read, hStdIn_Write; 
    HANDLE hStdOut_Read, hStdOut_Write; 
    SECURITY_ATTRIBUTES sAttr; 

    STARTUPINFOA StartInf; 
    PROCESS_INFORMATION procInf; 

    DWORD dwBytesToWrite,dwBytesReadFrom; 

    sAttr.nLength = sizeof(sAttr); 
    sAttr.bInheritHandle = TRUE; 
    sAttr.lpSecurityDescriptor = NULL; 

    CreatePipe(&hStdIn_Read,&hStdIn_Write,&sAttr,0); 
    CreatePipe(&hStdOut_Read,&hStdOut_Write,&sAttr,0); 

    //SetHandleInformation(hStdIn_Read, HANDLE_FLAG_INHERIT, 0); 
    //SetHandleInformation(hStdIn_Write, HANDLE_FLAG_INHERIT, 0); 

    memset(&StartInf,0, sizeof(StartInf)); 
    memset(&procInf,0,sizeof(procInf)); 

    StartInf.cb = sizeof(StartInf); 
    StartInf.dwFlags = STARTF_USESTDHANDLES; 
    StartInf.hStdError = hStdOut_Write; 
    StartInf.hStdOutput = hStdOut_Write; 
    StartInf.hStdInput = hStdIn_Read; 

    WriteFile(hStdIn_Write,Cmd,sizeof(Cmd),&dwBytesToWrite,NULL); 

    if(!CreateProcessA(NULL,"cmd.exe",NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW ,NULL,NULL,&StartInf,&procInf)) 
    { 
     MessageBoxA(m_hWnd, "Can't Create Process","Error",MB_OK | MB_ICONERROR); 
    } 
     WriteFile(hStdIn_Write,Cmd,sizeof(Cmd),&dwBytesToWrite,NULL); 

    BOOL bSUCCESS =TRUE; 
    Sleep(100); 
    while(bSUCCESS) 
    { 

     BOOL bResult = ReadFile(hStdOut_Read,Buff,70,&dwBytesReadFrom,NULL); 
     if(!bResult) 
     { 
      break; 
     } 
     Buff[dwBytesReadFrom]=0; 
     str+= Buff; 
     bSUCCESS = dwBytesReadFrom!=0; 
    } 
    m_Disp = str; 
    UpdateData(FALSE); 
    CloseHandle(hStdIn_Read); 
    CloseHandle(hStdIn_Write); 
    CloseHandle(hStdOut_Read); 
    CloseHandle(hStdOut_Write); 
} 

在上面的代碼中,在調試模式下對ReadFile函數的第一個調用返回 真實的數據,但它塊的最後一個電話,因爲沒有足夠的數據來讀取。

這裏是我的問題: 如何避免阻塞模式或得到的確切字節數讀?

商祺!

+0

一個很好的谷歌查詢是「窗口重疊io」。 –

回答

0

您可能希望使用PeekNamedPipe函數,該函數允許您查詢管道以查看在任何給定時間有多少數據可用。如果lpBufferNULL那麼沒有數據正在被讀取。