windows下C与C++执行cmd命令并实时获取输出

Posted DS小龙哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了windows下C与C++执行cmd命令并实时获取输出相关的知识,希望对你有一定的参考价值。

1. 前言

在windows下一般会使用系统的cmd命令或者其他现成的一些命令行可执行程序来完成一些操作,比如:调用ping命令来测试网络是否畅通、调用ffmpeg命令进行视频转码等等。为了能在软件界面上有更好的交互输出,都需要将命令执行的过程拿到,进行处理,然后在界面上进行显示,让用户知道程序正在正常运行,下面就介绍几种输出的获取方式。

当前开发环境: win10 64位 IDE-MSVC2017

2. 使用_popen执行进程

通过_popen打开进程进行执行,通过fgets获取进程的输出。

#include <stdio.h>
#include <string.h>

int run_cmd(const char * cmd)

    char MsgBuff[1024];
    int MsgLen=1020;
    FILE * fp;
    if (cmd == NULL)
    
        return -1;
    
    if ((fp = _popen(cmd, "r")) == NULL)
    
        return -2;
    
    else
    
        memset(MsgBuff, 0, MsgLen);

        //读取命令执行过程中的输出
        while (fgets(MsgBuff, MsgLen, fp) != NULL)
        
            printf("MsgBuff: %s\\n", MsgBuff);
        

        //关闭执行的进程
        if(_pclose(fp) == -1)
        
            return -3;
        
    
    return 0;


int main()

    //const char *cmd = "ffmpeg -i D:\\\\123.mp4 -vf reverse D:\\\\out\\\\out1.mp4";

    const char *cmd = "ping www.baidu.com";
    int ret = 0;
    ret = run_cmd(cmd);
    printf("命令执行结果:%d\\r\\n",ret);

    getchar();
    return 0;

3. CreateProcess重定向输出到文件

下面使用CreateProcess调用子进程运行,将输出保存在文件中,阻塞等待进程执行完毕。

int my_CreateProcess()

    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;

    _unlink("D:/out/output.log");

    HANDLE h = CreateFile((L"D:/out/output.log"),
        FILE_APPEND_DATA,
        FILE_SHARE_WRITE | FILE_SHARE_READ,
        &sa,
        OPEN_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    PROCESS_INFORMATION pi;
    STARTUPINFO si;
    BOOL ret = FALSE;
    DWORD flags = CREATE_NO_WINDOW;

    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags |= STARTF_USESTDHANDLES;
    si.hStdInput = NULL;
    si.hStdError = h;
    si.hStdOutput = h;

    TCHAR cmd[] = TEXT("ping www.baidu.com");
    ret = CreateProcess(NULL, cmd, NULL, NULL, TRUE, flags, NULL, NULL, &si, &pi);

    if (ret)
    
        WaitForSingleObject(pi.hProcess, INFINITE);
        printf("执行成功....\\n");
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        //关闭文件
        CloseHandle(h);
        return 0;
    
    //关闭文件
    CloseHandle(h);
    printf("执行失败....\\n");
    return -1;

4. CreateProcess重定向输出到管道

为了能实时获取CreateProcess打开进程运行时实时输出的结果,可以将CreateProcess的输出重定向到管道文件,CreateProcess将数据写到管道的写端,在父进程里再从管道的读端就能实时读取数据。

int my_CreateProcess()

    BOOL run_pipe;

    PROCESS_INFORMATION pi;
    STARTUPINFO si;
    BOOL ret = FALSE;
    DWORD flags = CREATE_NO_WINDOW;

    _unlink("D:/out/output.log");

    char pBuffer[210];
    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;
    HANDLE hReadPipe, hWritePipe;
    run_pipe=CreatePipe(&hReadPipe, &hWritePipe, &sa, 0);
    printf("run_pipe=%d\\n", run_pipe);

    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags |= STARTF_USESTDHANDLES; 
    si.hStdInput = NULL;
    si.hStdError = hWritePipe;
    si.hStdOutput = hWritePipe;

    TCHAR cmd[] = TEXT("ffmpeg -i D:\\\\123.mp4 -vf reverse D:\\\\out\\\\out1.mp4");

    ret = CreateProcess(NULL, cmd, NULL, NULL, TRUE, flags, NULL, NULL, &si, &pi);

    if (ret)
    
        while (true)
        
            DWORD ExitCode = 0;
            //判断进程是否执行结束
            GetExitCodeProcess(pi.hProcess, &ExitCode);
            if (ExitCode == STILL_ACTIVE) //正在运行
            
                DWORD RSize=0;
                BOOL run_s=0;
                run_s =ReadFile(hReadPipe, pBuffer,200,&RSize,NULL);
                pBuffer[RSize] = \\0;
                printf("返回结果:%d,%d,%s\\n", run_s, RSize, pBuffer);
            
            else //结束
            
                printf("执行完毕...\\n");
                break;
            
        

        //WaitForSingleObject(pi.hProcess, INFINITE);
        printf("执行成功....\\n");
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        return 0;
    
    printf("执行失败....\\n");
    return -1;

以上是关于windows下C与C++执行cmd命令并实时获取输出的主要内容,如果未能解决你的问题,请参考以下文章

windows下C与C++执行cmd命令并实时获取输出

使用 C++ 执行 CMD 命令

如何在windows c++中的cmd中运行命令后获取退出代码

Windows下如何通过CMD命令行获取串口名称?

使用 C++ 执行 CMD 命令

使c ++程序以交互方式将输入输出传递给Windows命令提示符