调用命令行程序并获取返回信息

调用命令行并获取返回信息是一件很有意思的事情,很多程序都会这么干,比如Visual Studio进行编译时,也是调用了一些命令行程序进行编译和链接,然后将其反馈信息输出到编译日志窗口。不过,调用一个命令行程序很简单,但获取其反馈信息并不是那么容易。当然如果知道怎么做,也不会很复杂。

思路如下:

  1. 创建一个匿名管道;
  2. 调用CreateProcess执行命令行程序并将其输出定位到匿名管道的写入端;
  3. 从匿名管道的读取端读取数据,那么读取到的数据就是命令行程序的输出信息;

这儿需要解释一下何谓管道,我的理解是:管道会提供一对端口,当向写入端口写入内容时,那么就可以在读取端口读取到相同的内容。匿名管道是管道中最简单的一种,通过调用CreatePipe函数可以创建一组匿名管道。

下面是一个调用命令行程序并获得返回值的C++函数源码:

 

复制代码
std::string ExeCmd(const char * pszCmd)
{
    //创建匿名管道
    SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
    HANDLE hRead, hWrite;
    if (!CreatePipe(&hRead, &hWrite, &sa, 0))
    {
        return "";
    }

    //设置命令行进程启动信息(以隐藏方式启动命令并定位其输出到hWrite)
    STARTUPINFO si = {sizeof(STARTUPINFO)};
    GetStartupInfo(&si);
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    si.wShowWindow = SW_HIDE;
    si.hStdError = hWrite;
    si.hStdOutput = hWrite;

    //启动命令行
    PROCESS_INFORMATION pi;
    if (!CreateProcess(NULL, (char *)pszCmd, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi))
    {
        return "";
    }

    //立即关闭hWrite
    CloseHandle(hWrite);

    //读取命令行返回值
    std::string strRet;
    char buff[1024] = {0};
    DWORD dwRead = 0;
    while (ReadFile(hRead, buff, 1024, &dwRead, NULL))
    {
        strRet.append(buff, dwRead);
    }
    CloseHandle(hRead);

    return strRet;
}
复制代码

 

这儿需要说明的是:为什么需要在启动命令行之后,会需要立即关闭hWrite?

原因是这样的:

首先,hWrite是Windows内核对象,内核对象有个特点,只有所有使用者都关闭该内核对象后,该内核对象才会真正关闭。这儿hWrite已经被上面的进程所使用了,所以此处关闭hWrite并不会导致该句柄失效。

其次,这样做有个好处在于,但命令行程序结束后,hWrite就会随之真正关闭。这样的话,才会让后续的ReadFile函数能够结束——否则它会一直等待直到hWrite被关闭(由于ReadFile是个同步函数,如果上面不关闭,以后永远没有关闭机会了)。

 

我在Visual Studio中,用一个对话框程序,简单测试一下这个函数:

 

void CTestPipeDlg::OnBnClickedOk()
{
    AfxMessageBox(ExeCmd("ping baidu.com").c_str());
}

 

结果如下:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值