天天看点

Windows进程通信方式之匿名管道

 父进程:

1.创建一个匿名管道

BOOL WINAPI CreatePipe(

  __out         PHANDLE hReadPipe,

  __out         PHANDLE hWritePipe,

  __in          LPSECURITY_ATTRIBUTES lpPipeAttributes,

  __in          DWORD nSize

);

创建一个匿名管道,返回管道的读写句柄。其中第三个参数是一个指向SECURITY_ATTRIBUTES结构的指针,它用来决定返回的句柄是否能被子进程所继承。通常被设为NULL,编写匿名管道时不可以。因为管道只可以在父子进程之间进行通信。

typedef struct _SECURITY_ATTRIBUTES {

  DWORD nLength;

  LPVOID lpSecurityDescriptor;

  BOOL bInheritHandle;

} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;

第三个参数用来所返回的句柄是否可以被新的子进程所继承,设为TRUE表示可以。

2.创建成功后,应当启动子进程,利用函数CreateProcess();

子进程:

在子进程中得到管道的句柄

HANDLE WINAPI GetStdHandle(

  __in          DWORD nStdHandle

);

具体程序如下:

父进程:

void CParentView::OnPipeCreate()

{

 // TODO: 在此添加命令处理程序代码

    SECURITY_ATTRIBUTES sa;

 sa.bInheritHandle=TRUE;

 sa.lpSecurityDescriptor=NULL;

 sa.nLength=sizeof(SECURITY_ATTRIBUTES );

 if(!CreatePipe(&hRead,&hWrite,&sa,0))

 {

  MessageBox("创建匿名管道失败");

  return;

 }

    STARTUPINFO sui;

    PROCESS_INFORMATION pi;

 ZeroMemory(&sui,sizeof(STARTUPINFO));//将结构体中成员全置为0,因为我们只是用了其中几个,否则其它都是随机的

 sui.cb=sizeof(STARTUPINFO);

 sui.dwFlags=STARTF_USESTDHANDLES;

 sui.hStdInput=hRead;

 sui.hStdOutput=hWrite;

 sui.hStdError=GetStdHandle(STD_ERROR_HANDLE);

    if(!CreateProcess("..\\Child\\Debug\\Child.exe",NULL,NULL,NULL,TRUE,0,NULL,NULL,&sui,&pi))

 {

  CloseHandle(hRead);

  CloseHandle(hWrite);

  hRead=NULL;

  hWrite=NULL;

  MessageBox("创建子进程失败");

  return;

 }

 else

 {

  CloseHandle(pi.hProcess);

  CloseHandle(pi.hThread);

 }

}

子进程:

void CChildView::OnInitialUpdate(void)

{

 hRead=GetStdHandle(STD_INPUT_HANDLE);

 hWrite=GetStdHandle(STD_OUTPUT_HANDLE);

}

继续阅读