在程序的开发过程中,经常会遇到调用第三方应用程序的情况,这个时候获取第三方程序的输出就事关重大。那么如何获取第三方程序的输出呢?
1.使用CreateProcess,利用管道机制。下面的代码获取了console.exe程序的输出,其参数为-a -b, 可根据情况而变。本程序利用了MFC库。
int main()
{
SECURITY_ATTRIBUTES sa;
HANDLE hRead,hWrite;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
if (!CreatePipe(&hRead,&hWrite,&sa,0)) {
printf("Error On CreatePipe()\n");
return 1;
}
PROCESS_INFORMATION pi;
STARTUPINFO si;
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError = hWrite;
si.hStdOutput = hWrite;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
if (!CreateProcess("console.exe", "-a -b",
NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi)) {
printf("Error on CreateProcess()\n");
return 1;
}
CloseHandle(hWrite);
const int BufferLength = 1024;
CString showedMsg = "";
char buffer[BufferLength + 1] = {0};
DWORD bytesRead;
while (ReadFile(hRead,buffer,BufferLength,&bytesRead,NULL)) {
showedMsg.Append(buffer);
Sleep(200);
}
if (showedMsg.Find("find Bugs") > 0) {
printf("Error \n");
return 1;
}
return 0;
}
2.使用ShellExecuteEx,可惜无法获得控制台的输出。
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{
TCHAR folderPath[_MAX_PATH];
_tcscpy_s(folderPath, _MAX_PATH, argv[0]);
_TCHAR* last = _tcsrchr(folderPath, _T('\\'));
*(last+1) = _T('\0');
DWORD dwExitCode = ERROR_SUCCESS;
SHELLEXECUTEINFO shExecInfo = {0};
shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
shExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
shExecInfo.lpVerb = _T("open");
shExecInfo.lpFile = _T("CmdParmInput.exe");
shExecInfo.lpParameters = _T("-r 4 Glad to meet you!");
shExecInfo.lpDirectory = folderPath;
shExecInfo.nShow = SW_SHOWNORMAL;
if( ShellExecuteEx(&shExecInfo) == FALSE ){
dwExitCode = GetLastError();
_tprintf(_T("Failed to launch \"%s %s\".\n"), shExecInfo.lpFile, shExecInfo.lpParameters);
} else {
_tprintf(_T("\"%s %s\" is launched. \n"), shExecInfo.lpFile, shExecInfo.lpParameters);
DWORD wait;
wait = WaitForSingleObject(shExecInfo.hProcess, INFINITE);
if (GetExitCodeProcess(shExecInfo.hProcess, &dwExitCode) == 0) {
dwExitCode = GetLastError();
}
switch (wait) {
case WAIT_OBJECT_0:
_tprintf(_T("\"%s %s\" is done.(ExitCode:%d) \n"), shExecInfo.lpFile, shExecInfo.lpParameters, dwExitCode);
break;
case WAIT_ABANDONED:
_tprintf(_T("\"%s %s\" is a abandoned mutex object.(ExitCode:%d) \n"), shExecInfo.lpFile, shExecInfo.lpParameters, dwExitCode);
break;
default:
_tprintf(_T("Faild to wait until \"%s %s\" is done.(ExitCode:%d) \n"), shExecInfo.lpFile, shExecInfo.lpParameters, dwExitCode);
break;
}
}
}
return nRetCode;
}