目录
匿名管道是用来父进程跟子进程通信的.还有一种是命名管道.不需要父子进程就可以进行通信的.今天先说匿名管道的. 匿名管道. 就是父进程创建子进程. 读取子进程数据.或者给子进程发送数据.当然子进程也可以给父进程发送数据.以及读取父进程发送过来的数据.
创建匿名管道,首先你要明白什么是管道. 管道你可以想象成一个管子. 我们通过这个管子发送数据. 如下图所示:
通过上图,我们就知道其实创建了两个管道. 分别是父进程读取的管道.以及 子进程读取的管道.相应的.子进程也可以对父进程读取的管道进行传输数据.父进程就可以读取了. 这段话可能难以理解.你可以这样想.
我父进程读取子进程使用第一个管道. 那么反正子进程写的话也是使用第一个管道.因为子进程写.我们父进程才能读.
首先你需要了解创建匿名管道的API
WINBASEAPI
BOOL
WINAPI
CreatePipe(
_Out_ PHANDLE hReadPipe,
_Out_ PHANDLE hWritePipe,
_In_opt_ LPSECURITY_ATTRIBUTES lpPipeAttributes,
_In_ DWORD nSize
);
关于这个API很简单.相比你过来看匿名管道.说明你已经知道这个API了. 只不过不知道管道概念.(我猜的);
这个API很简单.就是创建管道. 两个句柄.读取句柄跟写入句柄. 我们需要创建两个管道.
还需要注意的是,父进程创建子进程,必须让父进程句柄可继承.这个就是第三个属性.安全属性描述符中给即可.
那么说一下创建步骤吧.
1.创建一个安全属性描述符,设置句柄可继承 2.创建两个管道. 父读->子写 子读->父写的 3.重定向输出,将子进程的读 以及子进程的写重定向. 4.创建子进程 5.读取\写入数据给子进程.
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
int main()
{
HANDLE hParentRead, hParentWrite, hChildRead, hChildWrite; //创建4个句柄
STARTUPINFO si = { 0 }; //启动信息结构体
si.cb = sizeof(si);
PROCESS_INFORMATION pi = { 0 }; //进程信息结构体
DWORD dwWritedBytes = 0;
DWORD dwReadedBytes = 0;
DWORD dwBytesRead = 0;
DWORD dwTotalBytesAvail = 0;
DWORD dwBytesLeftThisMessage = 0;
SECURITY_ATTRIBUTES sa = { 0 }; //安全属性描述符
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE; //设置句柄可继承
//创建管道1. 父进程读 -> 子进程写入
BOOL bRet = CreatePipe(&hParentRead,
&hChildWrite,
&sa,
0);
//创建管道2. 子进程读->父进程写.
bRet = CreatePipe(&hChildRead,
&hParentWrite,
&sa,
0);
//这里将子进程写重定向到 stdout中. 子进程读取重定向到stdinput中
si.hStdInput = hChildRead;
si.hStdOutput = hChildWrite;
si.dwFlags = STARTF_USESTDHANDLES; //设置窗口隐藏启动
bRet = CreateProcess(NULL,
"cmd.exe", //创建cmd进程.默认寻找cmd进程.
NULL,
NULL,
TRUE,
CREATE_NO_WINDOW,
NULL,
NULL,
&si,
&pi);
char szBuffer[15] = "calc \n";
WriteFile(hParentWrite, szBuffer, 15, NULL, 0);//使用writeFile操作管道,给cmd发送数据命令.
return 0;
}