进程间通信实现子进程标准输出转移

Visual Studio之类的IDE,在编译的时候调用cl等编译链接工具,而编译器是命令行程序,visual studio能把编译器的标准输出显示到窗口文本框中。一直困惑于它的实现方式。今天,终于在数小时的花费后,掌握了解决之道,关键在于创建匿名管道,并将子进程标准输出指向管道写端,另外一头就能慢慢读了。

下面这个例子就是将"ping 127.0.0.1"原本在命令行窗口输出的内容,显示到窗口程序的消息框中 。以下的代码是Windows应用程序的一部分,需加到完整的程序中才能使用

void go(HWND hwnd)
{
    char * ping = "PING 127.0.0.1";      // 命令
    char  pbuf[1024];                        // 缓存
    DWORD len;                   
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    HANDLE hRead1, hWrite1, hReadDup1;   // 管道读写句柄
    BOOL b;
    SECURITY_ATTRIBUTES saAttr;
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
   saAttr.bInheritHandle = TRUE;      // 管道句柄是可被继承的
   saAttr.lpSecurityDescriptor = NULL; 
    
    // 创建匿名管道,管道句柄是可被继承的
    b = CreatePipe(&hRead1, &hWrite1, &saAttr, 1024);
    if (!b)
    {
        MessageBox(hwnd, "管道创建失败。","Information",0);
        return ;
    }
   
    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);
    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_HIDE;
   
    si.hStdOutput = hWrite1;         // 设置需要传递到子进程的管道写句柄

     // 创建子进程,运行ping命令,子进程是可继承的
    if (!CreateProcess(NULL, ping, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
    {
        itoa(GetLastError(), pbuf, 10);
        MessageBox(hwnd, pbuf,"Information",0);
        CloseHandle(hRead1);
        CloseHandle(hReadDup1);
        CloseHandle(hWrite1);
        return ;
    }

// 写端句柄已被继承,本地则可关闭,不然读管道时将被阻塞
    CloseHandle(hWrite1);    

  // 读管道内容,并用消息框显示
    len = 1000;
    DWORD l;
    while (ReadFile(hReadDup1, pbuf, len, &l, NULL))
    {
        if (l == 0) break;
        pbuf[len] = 0;
        MessageBox(hwnd, pbuf,"Information",0);
        len = 1000;
    }
    MessageBox(hwnd, "ReadFile Exit","Information",0);
    CloseHandle(hRead1);
    return ;
}

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值