编程论坛

 找回密码
 立即注册
广告联系qq1031180668广告位
查看: 193|回复: 0

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

[复制链接]
  • ta_mind

    2018-8-17 21:57
  • classn_01: 71 classn_02

    [LV.6]常住居民II

    983

    主题

    1704

    帖子

    3365

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    3365

    最佳新人活跃会员热心会员推广达人宣传达人灌水之王突出贡献优秀版主荣誉管理论坛元老

    发表于 2018-9-11 20:14:43 | 显示全部楼层 |阅读模式
    运行效果:

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

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

    源码:
    [C++] syntaxhighlighter_viewsource syntaxhighlighter_copycode
    #include <iostream>
    #include <string>
    #include <Windows.h>
    
    using namespace std;
    
    /*
    获取CMD执行结果
    cmdLine:要执行的命令
    */
    char *GetCmdRet(char *cmdLine);
    
    int main(void)
    {
            char *ret = GetCmdRet("ipconfig");
            cout << ret << endl;
            free(ret);
            cout << "\n====================换个命令玩玩====================\n" << endl;
            ret = GetCmdRet("dir");
            cout << ret << endl;
            free(ret);
            system("pause");
            return 0;
    }
    
    char *GetCmdRet(char *cmdLine)
    {
            HANDLE hRead = NULL, hWrite = NULL;
            PROCESS_INFORMATION pInfo = { 0 };
            SECURITY_ATTRIBUTES se = { 0 };
            STARTUPINFO sInfo = { 0 };
            char tmpCmd[1000000] = { 0 }, *retStr = NULL;
            DWORD dwLen = 0;
            string ret;
    
            se.nLength = sizeof(se);
            se.lpSecurityDescriptor = NULL;
            se.bInheritHandle = TRUE;
    
            // 创建一个匿名管道
            CreatePipe(&hRead, &hWrite, &se, 0);
    
            sInfo.cb = sizeof(sInfo);
            sInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; // 这两个常量分别用于设置隐藏窗口+输出目标
            sInfo.wShowWindow = SW_HIDE; // 隐藏窗口运行
            sInfo.hStdOutput = hWrite;        // 让其输出到这个管道去而不是输出到控制台
            sInfo.hStdError = hWrite;        // 错误信息也是输出到该管道
            sprintf_s(tmpCmd, MAX_PATH, "cmd.exe /c %s", cmdLine);
            CreateProcess(NULL, tmpCmd, NULL, NULL, TRUE, NULL, NULL, NULL, &sInfo, &pInfo);
            CloseHandle(hWrite);
    
            while (dwLen != -1)
            {
                    // 查看管道中是否有数据
                    PeekNamedPipe(hRead, NULL, NULL, NULL, &dwLen, NULL);
                    if (dwLen)
                    {
                            memset(tmpCmd, 0, MAX_PATH);
                            // 读取管道数据
                            ReadFile(hRead, tmpCmd, dwLen, &dwLen, NULL);
                            ret += tmpCmd;
                    }
                    else
                    {
                            DWORD dwExit = 0;
                            GetExitCodeProcess(pInfo.hProcess, &dwExit);
                            // 避免程序已经退出,但管道仍有数据的情况
                            if (dwExit != STILL_ACTIVE)
                            {
                                    CloseHandle(hRead);
                                    break;
                            }
                    }
                    // 一定要加个延时,否则可能有重复数据
                    Sleep(1);
            }
            retStr = (char *)malloc(sizeof(char)*ret.length() + 1);
            memset(retStr, 0, ret.length() + 1);
            lstrcpyn(retStr, ret.c_str(), ret.length() + 1);
            return retStr;
    }

    不积跬步,无以至千里
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    手机版|Archiver|小黑屋|sitemap|编程论坛 - 一个单纯的编程学习交流论坛 ( 豫ICP备15032706号 )

    GMT+8, 2018-12-17 09:07 , Processed in 1.145226 second(s), 27 queries .

    Powered by Discuz! X3.4

    © 2001-2013 Comsenz Inc.

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