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

/
//                                                                                      //
//         ------- 如何使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!为了这个我折腾了大半天。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皓月如我

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值