不学网

 找回密码
 立即注册

只需一步,快速开始

手机号码,快捷登录

查看: 104|回复: 0

[c/c++] 通过匿名管道获取CMD运行结果

[复制链接]
BiaoGe 发表于 2018-8-26 22:21:48 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
  1. #include <iostream>
  2. #include <string>
  3. #include <Windows.h>

  4. using namespace std;

  5. /*
  6. 获取CMD执行结果
  7. cmdLine:要执行的命令
  8. */
  9. char *GetCmdRet(char *cmdLine);

  10. int main(void)
  11. {
  12.         char *ret = GetCmdRet("ipconfig");
  13.         cout << ret << endl;
  14.         free(ret);
  15.         cout << "\n====================换个命令玩玩====================\n" << endl;
  16.         ret = GetCmdRet("dir");
  17.         cout << ret << endl;
  18.         free(ret);
  19.         system("pause");
  20.         return 0;
  21. }

  22. char *GetCmdRet(char *cmdLine)
  23. {
  24.         HANDLE hRead = NULL, hWrite = NULL;
  25.         PROCESS_INFORMATION pInfo = { 0 };
  26.         SECURITY_ATTRIBUTES se = { 0 };
  27.         STARTUPINFO sInfo = { 0 };
  28.         char tmpCmd[1000000] = { 0 }, *retStr = NULL;
  29.         DWORD dwLen = 0;
  30.         string ret;

  31.         se.nLength = sizeof(se);
  32.         se.lpSecurityDescriptor = NULL;
  33.         se.bInheritHandle = TRUE;

  34.         // 创建一个匿名管道
  35.         CreatePipe(&hRead, &hWrite, &se, 0);

  36.         sInfo.cb = sizeof(sInfo);
  37.         sInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; // 这两个常量分别用于设置隐藏窗口+输出目标
  38.         sInfo.wShowWindow = SW_HIDE; // 隐藏窗口运行
  39.         sInfo.hStdOutput = hWrite;        // 让其输出到这个管道去而不是输出到控制台
  40.         sInfo.hStdError = hWrite;        // 错误信息也是输出到该管道
  41.         sprintf_s(tmpCmd, MAX_PATH, "cmd.exe /c %s", cmdLine);
  42.         CreateProcess(NULL, tmpCmd, NULL, NULL, TRUE, NULL, NULL, NULL, &sInfo, &pInfo);
  43.         CloseHandle(hWrite);

  44.         while (dwLen != -1)
  45.         {
  46.                 // 查看管道中是否有数据
  47.                 PeekNamedPipe(hRead, NULL, NULL, NULL, &dwLen, NULL);
  48.                 if (dwLen)
  49.                 {
  50.                         memset(tmpCmd, 0, MAX_PATH);
  51.                         // 读取管道数据
  52.                         ReadFile(hRead, tmpCmd, dwLen, &dwLen, NULL);
  53.                         ret += tmpCmd;
  54.                 }
  55.                 else
  56.                 {
  57.                         DWORD dwExit = 0;
  58.                         GetExitCodeProcess(pInfo.hProcess, &dwExit);
  59.                         // 避免程序已经退出,但管道仍有数据的情况
  60.                         if (dwExit != STILL_ACTIVE)
  61.                         {
  62.                                 CloseHandle(hRead);
  63.                                 break;
  64.                         }
  65.                 }
  66.                 // 一定要加个延时,否则可能有重复数据
  67.                 Sleep(1);
  68.         }
  69.         retStr = (char *)malloc(sizeof(char)*ret.length() + 1);
  70.         memset(retStr, 0, ret.length() + 1);
  71.         lstrcpyn(retStr, ret.c_str(), ret.length() + 1);
  72.         return retStr;
  73. }
复制代码

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|不学网

GMT+8, 2018-9-19 05:07

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表