如何在父进程中读取子(外部)进程的标准输出和标准错误输出结果
最近接手一个小项目,要求使用谷歌的aapt.exe获取apk软件包中的信息。依稀记得去年年中时,有个同事也问过我如何获取被调用进程的输出结果,当时还研究了一番,只是没有做整理。今天花点时间,将该方法整理成文。(转载请指明出于breaksoftware的csdn博客)
在信息化非常发达的今天,可能已经过了江湖“武侠”草莽的时代。仅凭一己之力想完成惊人的创举,可谓难上加难。于是社会分工越来越明确:你擅长写驱动,你就去封装个驱动出来;他擅长写界面,就让他写套界面出来。如果你非常好心,可以将自己的研究成果开源,那么可能会有千万人受益。如果你想保持神秘感,但是还是希望别人可以分享你的成果,你可能会将模块封装出来供别人使用。比如你提供了一个DLL文件和调用方法样例。但是,实际情况并不是我们想的那么简单。比如我文前提到的问题:别人提供了一个Console控制台程序,我们将如何获取其执行的输出结果呢?这个问题,从微软以为为我们考虑过了,我们可以从一个API中可以找到一些端倪——CreateProcess。
设置标准输出和标准错误输出句柄#define NEWBUFFERSIZE 0x100#define EXECDOSCMD L"aapt.exe"int _tmain(int argc, _TCHAR* argv[]){ char* pBuffer = NULL; WCHAR wchFilePath[MAX_PATH] = {0}; DWORD dwSize = MAX_PATH - 1; if ( FALSE == GetModuleFileName(NULL, wchFilePath, dwSize) ) { return -1; } CString cstrFilePath = wchFilePath; int nIndex = cstrFilePath.ReverseFind('\\'); if ( nIndex == -1 ) { return -1; } cstrFilePath = cstrFilePath.Left(nIndex + 1); cstrFilePath += EXECDOSCMD; cstrFilePath += L"\""; cstrFilePath = L"\"" + cstrFilePath; if ( ExecDosCmd( cstrFilePath, &pBuffer ) && NULL != pBuffer ) { CString cstrBuffer = CA2W(pBuffer, CP_UTF8); delete [] pBuffer; wprintf(L"%s", cstrBuffer); }return 0;}这样,我们就可以拿到子进程输出结果并加以分析。我这儿简单处理了下,就输出来。也算善始善终吧。
附上工程。