从匿名管道谈重定向技术

原创 2004年09月24日 13:26:00

                                 匿名管道与重定向技术
 正文
    首先我们得理解一个定义:重定向
何谓重定向?可以先字面理解为:重新决定方向!在控制台程序中,将标准的输入、输出句柄用管道的读、写句柄替换,而控制台程序本身并不知道它的输入、输出句柄已发生了变化,它依然将相关句柄(实为管道的读写句柄)作为标准的输入、输出句柄来看待。当父进程和子进程进行数据通信时的情形是这样的:父进程将标准的输出端重定向匿名管道的写句柄,启动子进程,因为继承关系,子进程也具有了这一特点,它的标准输出也与管道的写句柄联系在一起了。此时的父进程在关闭管道写句柄之后(一定要关闭),就可以通过读句柄来取得子进程发出的数据了。
   为了说明这个实事,我小举一例子,说明如何在图形界面中调用控制台的标准输出。程序运行的结果如下图:

程序按如下步骤实现:

1、新建一对话框CMyGUIDlg, 再加入一编辑框,设置好编辑框的属性(多行,水平&&垂直滚动条,自滚动,want return)ID号为:IDC_EDIT1
在ClassWizard中为IDC_EDIT1加入一CEdit型变量。

CEdit m_edit1;

2、加入一工作线程,函数可以为全局,当然也可以作为static型的类成员。我们选择后者。
   static UINT TestThread(LPVOID p);

3、在OnOK()消息处理函数中,加入如下代码:

void CMyGUIDlg::OnOK()
{

    AfxBeginThread(TestThread, this);
    UpdateData(TRUE);
}

4、在线程函数我们加入如下代码:
UINT CMyDUIDlg::TestThread(LPVOID p)
{
 STARTUPINFO si;
 PROCESS_INFORMATION pi;
 // 管道读句柄
 HANDLE hRead;
 // 管道写句柄
 HANDLE hWrite;
 
 SECURITY_ATTRIBUTES saAttr;
 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
 saAttr.lpSecurityDescriptor = 0;
 saAttr.bInheritHandle = true;
 
 // 创建匿名管道
 if(!CreatePipe(&hRead, &hWrite, &saAttr, 0))
 {
  AfxMessageBox("创建管道失败!");
  return 0;
 }
  // 得到本进程的当前标准输出
  // HANDLE hTemp = GetStdHandle(STD_OUTPUT_HANDLE);
 
  // 设置标准输出到匿名管道
  // SetStdHandle(STD_OUTPUT_HANDLE, hWrite);
 
 si.cb = sizeof(STARTUPINFO);
 GetStartupInfo(&si); // 获取本进程的STARTUPINFO结构信息
 si.hStdError = hWrite;
 si.hStdOutput = hWrite;
 si.wShowWindow = SW_HIDE;
 si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; // 让子进程隐藏、标准输出生效
 
 CString strLine;
 strLine.Format("cl -h %d /?", (unsigned int)hWrite); // 命令行参数
// 创建子进程
 if (!CreateProcess(NULL, (LPSTR)(LPCTSTR)strLine, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi))
 {
    AfxMessageBox("创建子进程失败!");
    return 0;
 }
 
 // 恢复本进程的标准输出
 // SetStdHandle(STD_OUTPUT_HANDLE, hTemp);

 CloseHandle(hWrite);   // 关闭写句柄(一定要关闭)
 CString strOut;
 char ReadBuf[100] = {0};
 DWORD dwRead;
 // 读管道直至管道关闭
 while (ReadFile(hRead, ReadBuf,99, &dwRead, NULL))
 {
  strOut += ReadBuf;
  memset(ReadBuf, 0, 99); 
 }
 CMyDUIDlg* plg = (CMyDUIDlg*)p;
 plg->m_edit1.SetWindowText(strOut);
 plg->InvalidateRect(NULL);

 CloseHandle(hRead);
 
 return 0;
}


作如下说明:
 1、本程序调用的控制台输出是VC++中的cl.exe运行的结果。当然你也可以自己加入一些控制台的 测试程序,将strLine赋值你想测试的控制台程序名即可。
 2、此程序在XP+VC6中测试通过。

如何使用匿名管道输出重定向

VC++在多进程通讯中有一种很好的方法就是使用管道技术。对于很多的初学者来说,不知道IDE的具体原理是什么,作者也是一样,为此迷惑了很多年,也最近才弄清楚IDE是如何集成了其他的命令行软件的,比如VC...
  • kinker
  • kinker
  • 2006年02月28日 16:10
  • 1290

关于匿名管道,重定向PING中的数据。

//网上摘抄的例子:原示例有错误,经修改如下。// Pipe.cpp : Defines the entry point for the console application.//#include ...
  • Lpc_china
  • Lpc_china
  • 2010年08月29日 10:14
  • 2222

[读后感]从Code Review 谈如何做技术

[读后感]从Code Review 谈如何做技术
  • sleks
  • sleks
  • 2014年11月16日 05:33
  • 1389

如何对CMD窗口进行输入输出重定向

昨天xingnup (黑猫)发了个贴子问关于如何取得进程句柄的问题。http://community.csdn.net/Expert/topic/4351/4351488.xml?temp=.4895...
  • winehero
  • winehero
  • 2005年12月31日 15:32
  • 2243

进程通信之二 管道技术第二篇 匿名管道

上一篇《进程通信之二 管道技术第一篇 输入输出的重定向》示范了增加若干程序代码来完成程序输入输出的重定向,并提出了如果没有程序源代码,只有程序文件如何来完成重定向。本篇就介绍如何使用匿名管道来完成这一...
  • MoreWindows
  • MoreWindows
  • 2012年03月27日 10:15
  • 27552

从利用匿名管道实现可交互式远程超级终端cmd.exe说起

为了实现
  • bobopeng
  • bobopeng
  • 2014年10月23日 13:29
  • 1685

利用管道实现控制台程序输入输出的重定向

在vc++6.0 创建控制台程序,编译测试通过。支持UniCode控制台测试程序(and.exe)#include "stdafx.h"#include "stdio.h"int main(int a...
  • Mi_Bo
  • Mi_Bo
  • 2010年06月29日 16:46
  • 1190

匿名管道实现父子进程之间的通信....

/*匿名管道: 匿名管道可以实现父子进程的通信, 一个由另一个进程调用CreateProcess函数创建的进程称为子进程 我们在利用CreatePipe创建你民管道的时候会获得管道的读写句柄  子进...
  • yue7603835
  • yue7603835
  • 2011年11月15日 18:47
  • 5146

【匿名管道】重定向cmd.exe

匿名管道通信——重定向CMD.EXE 匿名管道 匿名管道无非就是系统内核管理的一块内存区域,把这个文件的句柄分为读写,以程序使用。 实现原理 所以重定向cmd.exe的标准输入输...
  • yzt33
  • yzt33
  • 2015年03月21日 16:07
  • 760

谈技术牛人以及技术的价值

老板尊重的都是别人家的技术,别人家的技术大牛? 创业团队里没有牛人是痛苦的,有了牛人就一帆风顺了么? 或者,明明牛人曾经就在身边,却一不留神错过了,这种事情你意识到了么? 总有创业者会疑...
  • ones123654
  • ones123654
  • 2015年10月08日 10:45
  • 216
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:从匿名管道谈重定向技术
举报原因:
原因补充:

(最多只允许输入30个字)