这是我第一次出教程,若不好可在评论回复我哦(・。・)~~~~~
注:匿名管道是一个未命名的单相管道,通常用来在一个父进程和一个子进程之间的传输数据。匿名管道只能实现本地机器上两个进程间的通讯,却不能实现网络的通讯。
- 打开编译器VS2019
- 创建MFC应用程序
- 设置项目名称“Parent”,解决方案名称为“进程间通讯-匿名管道”
4.应用程序类型选择“基于对话框”
5. 用户界面功能选中“最小化框”“最大化框”,再去掉“ ‘关于’框”。
- 点击“完成”
- 绘制窗口。
“启动子进程”设置属性,在“杂项”里修改ID——IDC_BTN_BEGIN
“写入数据”设置属性,在“杂项”里修改ID——IDC_BTN_WRITE
“读取数据”设置属性,在“杂项”里修改ID——IDC_BTN_READ
- 双击“启动子进程”在“OnBnClickedBtnBegin()”
创建两个成员变量:
HANDLE m_hRead;
HANDLE m_HWrite;
记得在构造函数里初始化一下哦~~~~~~~~
- CreatePipe函数:
BOOL CreatePipe(
PHANDLE hReadPipe,
PHANDLE hWritePipe,
LPSECURITY_ATTRIBUTES lpPipeAttributes,
DWORD nSize
);
hReadPipe
[out] 指向接收管道读取句柄的变量的指针。
hWritePipe
[out] 指向接收管道写句柄的变量的指针。
lpPipeAttributes
[in]指向SECURITY_ATTRIBUTES结构的指针,该结构确定子进程是否可以继承返回的句柄。 如果 lpPipeAttributes 为 NULL,则不能继承句柄。
该结构的 lpSecurityDescriptor 成员为新管道指定了一个安全描述符。 如果 lpPipeAttributes 为 NULL,则管道获得一个默认的安全描述符。 管道的默认安全描述符中的 ACL 来自创建者的主要令牌或模拟令牌。
nSize
[in] 管道缓冲区的大小,以字节为单位。 尺寸只是一个建议; 系统使用该值来计算适当的缓冲机制。 如果此参数为零,则系统使用默认缓冲区大小。
// TODO: 在此添加控件通知处理程序代码
SECURITY_ATTRIBUTES sa;
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
sa.nLength = sizeof(sa);
//创建匿名管道
if (!CreatePipe(&m_hRead, &m_hWrite, &sa, 0))
{
MessageBox(L"创建匿名管道失败.Error", L"", MB_OK | MB_ICONERROR);
return;
}
STARTUPINFO si = { 0 };
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = m_hRead;
si.hStdOutput = m_hWrite;
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
PROCESS_INFORMATION pi;
//创建子进程
if (!CreateProcess(L"Sub.exe", NULL, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi))
{
CloseHandle(m_hRead);
CloseHandle(m_hWrite);
m_hRead = NULL;
m_hWrite = NULL;
MessageBox(L"创建Sub.exe", L"温馨提示", MB_OK | MB_ICONERROR);
return;
}
else
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
注:必须要用父进程启动子进程,不能单独启动子进程!!!
- 对话框中双击“写入数据”,在“OnBnClickedBtnRead()”中
// TODO: 在此添加控件通知处理程序代码
wchar_t szBuffer[100] = { 0 };
DWORD dwRead;
if (!ReadFile(m_hRead, szBuffer, sizeof(szBuffer), &dwRead, NULL))
{
MessageBox(L"ReadFile Error");
return;
}
MessageBox(szBuffer);
- 对话框中双击“读取数据”,在“OnBnClickedBtnWrite()”中
// TODO: 在此添加控件通知处理程序代码
wchar_t szBuffer[] = L"Hello!——父进程";
DWORD dwWrite = 0;
if (!WriteFile(m_hWrite, szBuffer, wcslen(szBuffer) * 2 + 1, &dwWrite, NULL))
{
MessageBox(L"WriteFile Error!", L"");
return;
}