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 }
![]()