改变DOS程序的标准输出,用一个管道的写端口替换他,然后windows程序从管道的读端口读出来。
下面这个示例的函数可以把给定的DOS命令执行一遍,并把DOS下的输出内容记录在buffer中。同时示范了匿名管道重定向输出的用法:
- //执行CMD命令返回命令结果
- BOOLGetCmdResult(const char * szDosCmd, CString &sRetVal)
- {
- //创建管道
- SECURITY_ATTRIBUTES sa;
- HANDLE hRead,hWrite;
- sa.nLength = sizeof(SECURITY_ATTRIBUTES);
- sa.lpSecurityDescriptor = NULL;
- sa.bInheritHandle = TRUE;
- if (!CreatePipe(&hRead,&hWrite,&sa,0))
- {
- return FALSE;
- }
- //组装命令行,长达1K的命令行,应该够用
- char command[1024];
- strcpy(command,"Cmd.exe /C ");
- strcat(command,szDosCmd);
- //返回进程在启动时被指定的STARTUPINFO结构
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- si.cb = sizeof(STARTUPINFO);
- GetStartupInfo(&si);
- si.hStdError = hWrite; //把创建进程的标准错误重定向到管道输入
- si.hStdOutput = hWrite; //把创建进程的标准输出重定向到管道输入
- si.wShowWindow = SW_HIDE;
- si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
- //执行命名,创建子进程
- //第五个参数bInHeritHandles也是一定要设置为TRUE,因为既然要让新进程能输出信息到调用他的进程里,就必须让新的进程继承调用进程的句柄.
- if (!CreateProcess(NULL, command,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))
- {
- CloseHandle(hWrite);
- CloseHandle(hRead);
- return FALSE;
- }
- //关闭管道输入
- CloseHandle(hWrite);
- //读取管道输出
- DWORD dwRead = 0;
- DWORD dwBlock = 4096;
- char szBuffer[4096 + 1] = { 0 };
- char buffer[4096] = {0};
- DWORD bytesRead;
- while (ReadFile(hRead,buffer,4095,&bytesRead,NULL))
- {
- sRetVal += szBuffer;
- }
- //关闭管道输出
- CloseHandle(hRead);
- return TRUE;
- }