通过匿名管道获取CMD运行结果
1 #include <iostream> 2 #include <string> 3 #include <Windows.h> 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 else 64 { 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 }