背景
以前有个人咨询我说,要怎么编程实现获取控制台窗口或者是CMD窗口输出的数据内容。当时水平有限,很多知识还不是很了解。但是凭借着有一点基础,而且之前在网络上浏览过相关的技术实现,还有些印象,便回答ta说,可以用匿名管道的方式来实现。
管道是一种用于在进程间共享数据的机制,其实质是一段共享内存。Windows系统为这段共享的内存设计采用数据流I/0的方式来访问。由一个进程读、另一个进程写,类似于一个管道两端,因此这种进程间的通信方式称作“管道”。
管道分为匿名管道和命名管道。匿名管道只能在父子进程间进行通信,不能在网络间通信,而且数据传输是单向的,只能一端写,另一端读。命令管道可以在任意进程间通信,通信是双向的,任意一端都可读可写,但是在同一时间只能有一端读、一端写。
后来,自己想起这件事,开始自己动手实现。没想到真的可以通过创建匿名管道的方式来实现。现在,我就把程序实现的过程和原理整理成文档,分享给大家。
函数介绍
CreatePipe 函数创建一个匿名管道,并从中得到读写管道的句柄。
函数声明
BOOL WINAPICreatePipe(
_Out_PHANDLEhReadPipe,
_Out_PHANDLEhWritePipe,
_In_opt_LPSECURITY_ATTRIBUTESlpPipeAttributes,
_In_DWORDnSize
);
参数
hReadPipe[out]
返回一个可用于读管道数据的文件句柄。
hWritePipe[out]
返回一个可用于写管道数据的文件句柄。
lpPipeAttributes[in, optional]
传入一个SECURITY_ATTRIBUTES结构的指针,该结构用于决定该函数返回的句柄是否可被子进程继承。如果传NULL,则返回的句柄是不可继承的。
该结构的lpSecurityDescriptor成员用于设定管道的安全属性,如果传NULL,那么该管道将获得一个默认的安全属性,该属性与创建该管道的用户账户权限ACLs的安全令牌(token)相同。
nSize[in]
管道的缓冲区大小。但是这仅仅只是一个理想值,系统根据这个值创建大小相近的缓冲区。如果传入0 ,那么系统将使用一个默认的缓冲区大小。
返回值
如果函数成功,则返回值不为零。