break; default: return ""; break; } return cmd; } 这个方法很简单,就不多讲了,类的执行核心在DoCommand中,代码如下: const string CAPKHelper::DoCommand( const string cmd ) { STARTUPINFO si; SECURITY_ATTRIBUTES sa; PROCESS_INFORMATION pi; string str=""; char ReadBuf[1024] = {0}; DWORD ReadNum; HANDLE hRead; // 管道读句柄 HANDLE hWrite; // 管道写句柄 sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = true; sa.lpSecurityDescriptor = NULL; BOOL bRet = CreatePipe(&hRead, &hWrite, &sa, 0); // 创建匿名管道 if(!bRet) return ""; GetStartupInfo(&si); si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; si.hStdOutput = hWrite; si.hStdError = hWrite; si.hStdInput = hRead; bRet = CreateProcess(NULL, (char *)cmd.c_str(), NULL, NULL, true, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi); if (!bRet) { CloseHandle(hRead); CloseHandle(hWrite); return ""; } CloseHandle(hWrite); WaitForSingleObject(pi.hProcess, 3000); //等待执行返回 while(ReadFile(hRead, ReadBuf, sizeof(ReadBuf)-1, &ReadNum, NULL)) { ReadBuf[ReadNum] = '\0'; str = str + ReadBuf; } str = utf2ansi(str.c_str(), str.size()); CloseHandle(hRead); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return str; } 这段代码是典型的 WIN32 代码,首先通过 CreatePipe()创建管道,设置子进程的读写 句柄,然后创建子进程并获取返回信息,在这里需要注意的是AAPT返回的是 UTF-8 编码的 字符串,如果APK 软件名为中文的话我们直接获取的话在程序中就会显示为乱码,所以需要 加上这行代码:str = utf2ansi(str.c_str(), str.size()),它的作用就是将UTF8格式编 码的字符串转换为ANSI编码: std::string utf2ansi(LPCSTR pszSrc, int nLen) { int nSize = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)pszSrc, nLen, 0, 0); if(nSize <= 0) return NULL; WCHAR *pwsz = new WCHAR[nSize+1]; if( NULL == pwsz) return NULL; MultiByteToWideChar(CP_UTF8, 0,(LPCSTR)pszSrc, nLen, pwsz, nSize); pwsz[nSize] = 0; char *psz = new char[nSize+1]; WideCharToMultiByte(CP_ACP, 0, pwsz, nSize, psz, nSize, NULL, NULL); string str = psz; delete pwsz; delete psz; return str; } GetInfo()、Install()、Uninstall()对返回的数据进行分析并给出最终的执行结果, Install()与 Uninstall()代码很简单,就不列举了,大家可以看已查看源码,具体的说说 GetInfo(),它的处理还是相对较难的,GetInfo()通过DoCommand()接收到类似图6的数据 并进行提取,然后设置到类的相应成员当中,为了使字符串操作简化,我使用了基于 STL 模板类中的 string 类,这个类很强大,提供了字符串除正则表达式外的一切操作,这使得 GetInfo()的代码量更少更美观,截取一段处理代码如下: CloseHandle(hWrite); WaitForSingleObject(pi.hProcess, 3000); //等待执行返回 while(ReadFile(hRead, ReadBuf, sizeof(ReadBuf)-1, &ReadNum, NULL)) { ReadBuf[ReadNum] = '\0'; str = str + ReadBuf; } str = utf2ansi(str.c_str(), str.size()); CloseHandle(hRead); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return str; } void CAPKHelper::GetInfo() { string str; str = DoCommand(PrePare(APKF_INFO)); string::size_type posbegin; string::size_type posend; posbegin = str.find(errorstr); //APK文件是否有效 if (posbegin != string::npos) { m_softName = ""; m_PkgName = ""; m_iconFile = ""; m_Version = ""; m_OSVersion = ""; m_FileSize = ""; |