1 #include2 #include 3 #include 4 5 using namespace std; 6 7 /* 8 获取CMD执行结果 9 cmdLine:要执行的命令10 */11 char *GetCmdRet(char *cmdLine);12 13 int main(void)14 {15 char *ret = GetCmdRet("ipconfig");16 cout << ret << endl;17 free(ret);18 cout << "\n====================换个命令玩玩====================\n" << endl;19 ret = GetCmdRet("dir");20 cout << ret << endl;21 free(ret);22 system("pause");23 return 0;24 }25 26 char *GetCmdRet(char *cmdLine)27 {28 HANDLE hRead = NULL, hWrite = NULL;29 PROCESS_INFORMATION pInfo = { 0 };30 SECURITY_ATTRIBUTES se = { 0 };31 STARTUPINFO sInfo = { 0 };32 char tmpCmd[1000000] = { 0 }, *retStr = NULL;33 DWORD dwLen = 0;34 string ret;35 36 se.nLength = sizeof(se);37 se.lpSecurityDescriptor = NULL;38 se.bInheritHandle = TRUE;39 40 // 创建一个匿名管道41 CreatePipe(&hRead, &hWrite, &se, 0);42 43 sInfo.cb = sizeof(sInfo);44 sInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; // 这两个常量分别用于设置隐藏窗口+输出目标45 sInfo.wShowWindow = SW_HIDE; // 隐藏窗口运行46 sInfo.hStdOutput = hWrite; // 让其输出到这个管道去而不是输出到控制台47 sInfo.hStdError = hWrite; // 错误信息也是输出到该管道48 sprintf_s(tmpCmd, MAX_PATH, "cmd.exe /c %s", cmdLine);49 CreateProcess(NULL, tmpCmd, NULL, NULL, TRUE, NULL, NULL, NULL, &sInfo, &pInfo);50 CloseHandle(hWrite);51 52 while (dwLen != -1)53 {54 // 查看管道中是否有数据55 PeekNamedPipe(hRead, NULL, NULL, NULL, &dwLen, NULL);56 if (dwLen)57 {58 memset(tmpCmd, 0, MAX_PATH);59 // 读取管道数据60 ReadFile(hRead, tmpCmd, dwLen, &dwLen, NULL);61 ret += tmpCmd;62 }63 else64 {65 DWORD dwExit = 0;66 GetExitCodeProcess(pInfo.hProcess, &dwExit);67 // 避免程序已经退出,但管道仍有数据的情况68 if (dwExit != STILL_ACTIVE)69 {70 CloseHandle(hRead);71 break;72 }73 }74 // 一定要加个延时,否则可能有重复数据75 Sleep(1);76 }77 retStr = (char *)malloc(sizeof(char)*ret.length() + 1);78 memset(retStr, 0, ret.length() + 1);79 lstrcpyn(retStr, ret.c_str(), ret.length() + 1);80 return retStr;81 }