/
//                                                                                      //
//         ------- 如何使cmd的输入和输出重定向到管道中 -------       //
//        ------- 用这种方法可以将指令写入cmd并抓取输出 -------     //
//                                                                                     //

//    --------- chendana's implements, modified by chenth ---------    //
#include <windows.h>
#include <iostream>
#include <string>

using namespace std;
HANDLE hRead1,hWrite1;   //读句柄,写句柄
HANDLE hRead2,hWrite2;   //读句柄,写句柄
HANDLE hCmd;
int CreateCMD(HANDLE &hReadPipe1,HANDLE &hWritePipe1,//匿名管道1读写句柄
               HANDLE &hReadPipe2,HANDLE &hWritePipe2,//匿名管道2读写句柄
               HANDLE &hProcess)//创建的CMD.EXE进程句柄
{
    int ret;
    SECURITY_ATTRIBUTES sa;
    sa.nLength=12;
    sa.lpSecurityDescriptor=0;
    sa.bInheritHandle=true;
    ret=CreatePipe(&hReadPipe1,&hWritePipe1,&sa,0);
    if (ret == 0)
    {
        return -1;
    }
    ret=CreatePipe(&hReadPipe2,&hWritePipe2,&sa,0);
    if (ret == 0)
    {
        return -1;
    }

STARTUPINFO si;
    ZeroMemory(&si,sizeof(si));
    si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
    si.wShowWindow = SW_SHOW;//SW_HIDE

//创建进程且重定向标准输入输出

//将其标准输入设置为hReadPipe2
    //将其标准输出和错误输出设置为hWritePipe1
    //通信逻辑见上图
    si.hStdInput = hReadPipe2;
    si.hStdOutput = si.hStdError = hWritePipe1;
    char cmdLine[] = "cmd";
    PROCESS_INFORMATION ProcessInformation;
    ret=CreateProcess(NULL,(LPSTR)cmdLine,NULL,NULL,1,0,NULL,NULL,&si,&ProcessInformation);
    if (ret == 0)
    {
        return -1;
    }
    hProcess=ProcessInformation.hProcess;
    return 0;
}

//****************************************************************************
//此函数用来写已建立的管道
int WriteCMD(char* cmdBuffer,HANDLE hWritePipe2)
{
    DWORD lBytesWrite;
    char cmd_tmp[1024]="";
    printf("writing.../n");
    sprintf_s(cmd_tmp,1024,"%s%s",cmdBuffer,"/r/n");
    if (!WriteFile(hWritePipe2,(LPTSTR)cmd_tmp,strlen(cmd_tmp),&lBytesWrite,NULL))
    {
        return -1;
    }
    return 0;
}
//****************************************************************************
//此函数用来读已建立的管道
int ReadCMD(HANDLE hReadPipe1,string &cmdResult){
    BOOL ret;
    DWORD lBytesRead;
    char *buffer=new char [1024];
    while(true)
    {
        printf("reading.../n");
        Sleep(99);
        memset(buffer,0,1024);
        ret=ReadFile(hReadPipe1,buffer,1023,&lBytesRead,0);
        if (ret == 0)
        {
            delete buffer;
            return -1;
        }
        buffer[lBytesRead]='/0';
        cmdResult += buffer;
        if(buffer[lBytesRead-1]=='>')
        {
            delete buffer;
            return 0;
        }
    }
    delete buffer;
    return 0;
}
//*****************************************************************************
//此函数用来关闭管道
void CloseCMD(HANDLE hReadPipe1,HANDLE hWritePipe1,//匿名管道1读写句柄
              HANDLE hReadPipe2,HANDLE hWritePipe2,//匿名管道2读写句柄
              HANDLE hProcess)//创建的CMD.EXE进程句柄
{
    CloseHandle(hReadPipe1);
    CloseHandle(hWritePipe1);
    CloseHandle(hWritePipe2);
    CloseHandle(hReadPipe2);
    TerminateProcess(hProcess,0);
}
//*****************************************************************************
//此函数用来清空管道数据
void EmptyPipe(HANDLE hReadPipe1){
    BOOL ret;
    DWORD bytesRead;
    char *buffer=new char [1024];
    while(true)
    {
        memset(buffer,0,1024);
        ret=PeekNamedPipe(hReadPipe1,buffer,1024,&bytesRead,0,0);
        if (bytesRead==0||!ret)
        {
            delete buffer;
            return;
        }
        ReadFile(hReadPipe1,buffer,bytesRead,&bytesRead,0);
    }
}

//   ------------------ Sample codes by chenth ------------------   //
int main( int argc, char *argv[] )
{
    string result;
    DWORD dw;
   
    if (CreateCMD(hRead1,hWrite1,hRead2,hWrite2,hCmd) < 0)
    {
        printf("CreateCMD 失败   ");
        dw = GetLastError();
        printf("GetLastError-->%u/n", dw);
        ExitProcess(dw);
        return -1;
    }
    if (WriteCMD("dir",hWrite2) < 0)
    {
        printf("WriteCMD 失败   ");
        dw = GetLastError();
        printf("GetLastError-->%u/n", dw);
        ExitProcess(dw);
        return -1;
    }
    if (ReadCMD(hRead1,result) < 0)
    {
        printf("ReadCMD 失败   ");
        dw = GetLastError();
        printf("GetLastError-->%u/n", dw);
        ExitProcess(dw);
        return -1;
    }
    printf("**********************************************/n");
    printf("%s/n",result.c_str());
    printf("**********************************************/n");
    CloseCMD(hRead1,hWrite1,hRead2,hWrite2,hCmd);
    return 0;
}

//很重要一点:需要在IDE中把编码设置成“多字节字符集(MBCS)”而不是UNICODE!为了这个我折腾了大半天。

如何使cmd的输入和输出重定向到管道中(用这种方法可以将指令写入cmd并抓取输出)相关推荐

  1. 输入重定向,输出重定向,管道相关内容及实现方法

    近期,通过实现shell了解了输入重定向,输出重定向,管道- 用自己的话总结定义: 输入重定向:把<右边的文件的内容输入到<左边的命令中. 输出重定向:把运行>左边命令得出的结果输入 ...

  2. 22、输入和输出重定向,管道,命令连接符,命令替换符

    2019独角兽企业重金招聘Python工程师标准>>> (一)输入/输出重定向 标准输入--standard input:从键盘上输入 标准输出--standard output:在 ...

  3. linux将什么定向到文件,linux – 将输出重定向到C中的文件

    这是我用dup2测试的结果 更微妙的一点是在正确的时间记住fflush :)否则,你会得到非常令人惊讶的结果. 此外,更喜欢fileno而不是硬编码1(stdout)2(stderr). 重定向std ...

  4. shell 的here document 用法、输入/输出重定向

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 什么是Here Document Here Document 是在Linux Shell 中的一种特 ...

  5. linux输出重定向%3e退出,Linux学习笔记——第二章:Linux的用户接口与文本编辑器...

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 2.1 Shell 2.1.3 命令和文件名的自动补齐功能 在命令和文件名输入到一半时,按Tab可以自动匹配命令和文件名 ...

  6. linux将屏幕输出内容转储到文件,Linux实时将所有输出重定向到文件

    Linux的重定向机制十分好用,我们经常需要在服务器上挂起一个服务程序,然后将该程序的所有输出重定向到某个文件,这样即使我们注销了用户,程序依然在linux服务器上运行着. 但是重定向的输出经常无法实 ...

  7. linux输出重定向跨服务器,【一看就懂,一听就会】Linux重定向详解——输出重定向...

    一.啥是重定向?? Linux重定向定向分为两种,一种输入重定向,一种是输出重定向: 从字面上理解,输入输出重定向(重新定义方向) 就是「改变输入与输出的方向」的意思. 总结: 输入方向就是我们人类从 ...

  8. python 重定向输入_python怎么重定向输入

    匿名用户 1级 2017-05-31 回答 控制台重定向 最简单常用的输出重定向方式是利用控制台命令.这种重定向由控制台完成,而与Python本身无关. Windows命令提示符(cmd.exe)和L ...

  9. 【shell】linux输出重定向|输出重定向2>1

    目录 即看即用 详细 知识铺垫 说明 [shell]输出重定向2>&1 即看即用 标准输出: ls thereisno 1> out.txt  标准输出重定向  也可以不加1写成 ...

最新文章

  1. 用拉链法实现哈希算法的运算
  2. iOS 导航栏遮挡视图
  3. 《unix设备驱动》内存分配
  4. 旋转根组件 Learn Unreal Engine (with C++)
  5. python 主函数 输入
  6. 数据结构与算法——二叉排序树详解以及代码实现
  7. leetcode 加一
  8. httpcode状态码
  9. Linux下安装Apache Maven安装
  10. zabbix3.2学习笔记(四):设置sendEmail告警动作
  11. Eclipse tooltip变黑的修正
  12. 【算法竞赛-入门经典】计算并输出1+2的值
  13. 等价类划分法测试用例设计
  14. 使用 React 开发小程序
  15. 饼图加引导线_如何在饼形图中添加引导线(Excel)/
  16. 大一C语言总结贴(持更) Part1 输出菱形
  17. linux系统可以玩星际争霸吧,《星际争霸》4.0版本更新说明
  18. Python笔记(二十)_多态、组合
  19. 跟我一起玩编程Python
  20. 在word中插入较为清晰的CAD框线图方法

热门文章

  1. 问题小结(2)-dialog内容动态变化(调用系统方法时)
  2. 一天一点T-SQL:使用登录触发器进行安全管控
  3. [导入]extjs 教程
  4. 【面试题】Spring框架中Bean的生命周期
  5. 数据结构基础温故-6.查找(下):哈希表
  6. Spring cloud zuul跨域(一)
  7. docker 安装mysql
  8. STL源码分析-bitset
  9. nodejs中EventEmitter
  10. Qt5:为窗口 创建工具栏 toobar