我正在开发一个类似远程shell的程序。 为了在远程机器上运行命令,我创建了一个cmd.exe进程,并将其标准输入和标准输出重定向到一对管道。我使用这些管道发送命令并获得结果。我使用ReadFile函数从cmd返回命令的输出.exe但我不知道我必须从管道读取的确切数据量。因此,如果数据未准备好,则读取文件进入阻止模式并等待数据。
我使用的是MSVC++ 2010,我的操作系统是Win7。以下是我的代码的一部分作为示例:
void CpipesDlg::OnBnClickedBtnredirstd()
{
char Cmd[]="dir *.*rn";
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 函数的第一次调用返回真实数据,但最后一次调用 IT 会阻塞,因为没有足够的数据可供读取。
这是我的问题:如何避免阻塞模式或获取确切的字节数以进行读取?
问候!
您可能希望使用PeekNamedPipe
函数,该函数允许您询问管道以查看在任何给定时间有多少可用数据。如果lpBuffer
NULL
则不读取任何数据。