使用MFC创建匿名管道时出现一些问题,我是按照孙鑫老师的VC++深入详解的第17课的例子里面的步骤写的
代码和书上的完全一样,没有哦发现有什么不同的地方
但是第一次创建管道的时候在建立子进程时,子进程无法获取父进程的读写管道的句柄,但是当我再次创建管道时,子进程能够读取父进程的低些句柄,但是读取到的却是第一次创建管道时父进程的读写句柄,即以后每次创建一个子进程,他获得的都是上一个父进程的读写句柄,而不是本次所重新创建的管道的读写句柄。
不知道这是为什么?书上的步骤是这样的:
对于父进程:
1、创建匿名管道
2、创建子进程
3、编写写入数据到管道的代码;
4、编写从管道读取数据的代码;对于子进程:
1、在建立窗口的时候获取父进程的读写句柄
2、编写相关到写入数据的代码;
3、编写从管道读取数据的代码;
对应的代码如下:父进程步骤1和2代码
void CParentView::OnPipeCreate()
{
// TODO: Add your command handler code here
SECURITY_ATTRIBUTES sa;
sa.bInheritHandle=true;
sa.lpSecurityDescriptor=NULL;
sa.nLength=sizeof(SECURITY_ATTRIBUTES); STARTUPINFO sui;
PROCESS_INFORMATION pi;
ZeroMemory(&sui,sizeof(STARTUPINFO));
sui.cb=sizeof(STARTUPINFO);
sui.dwFlags=STARTF_USESTDHANDLES;
sui.hStdInput=hRead;
sui.hStdOutput=hWrite;
sui.hStdError=GetStdHandle(STD_ERROR_HANDLE);
if(!CreatePipe(&hRead,&hWrite,&sa,0))
{
//CloseHandle(hRead);
//CloseHandle(hWrite);
AfxMessageBox("管道创建失败!");
return;
}
CString str1,str2;
str1.Format("hRead=%d",hRead);
str2.Format("hWrite=%d",hWrite);
AfxMessageBox(str1);
AfxMessageBox(str2); if(!CreateProcess("..\\Child\\Debug\\Child.exe",NULL,NULL,NULL,true,0,NULL,NULL,&sui,&pi))
{
CloseHandle(hRead);
CloseHandle(hWrite);
hRead=NULL;//防止在析构函数中再次调用CloseHandle
hWrite=NULL;
AfxMessageBox("进程创建失败!");
return;
}
else
{
CloseHandle(pi.hProcess);//在这里关闭
CloseHandle(pi.hThread);
}
}父进程步骤3代码
void CParentView::OnPipeWrite()
{
// TODO: Add your command handler code here
char buf[]="父类数据!";
DWORD dwWrite; if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))
{
AfxMessageBox("写入管道失败!");
return;
}
}
父进程步骤4代码
void CParentView::OnPipeRead()
{
// TODO: Add your command handler code here
char buf[100];
DWORD dwRead; if(!ReadFile(hRead,buf,100,&dwRead,NULL))
{
AfxMessageBox("读取管道失败!");
return;
} AfxMessageBox(buf);
}子进程代码:
子进程步骤1代码void CChildView::OnInitialUpdate()
{
CView::OnInitialUpdate();
// TODO: Add your specialized code here and/or call the base class
hRead=GetStdHandle(STD_INPUT_HANDLE);
hWrite=GetStdHandle(STD_OUTPUT_HANDLE); if(INVALID_HANDLE_VALUE ==hRead)
AfxMessageBox("hRead获取失败!");
if(INVALID_HANDLE_VALUE ==hWrite)
AfxMessageBox("hWrite获取失败!"); CString str1,str2;
str1.Format("child hRead=%d",hRead);
str2.Format("Child hWrite=%d",hWrite);
AfxMessageBox(str1);
AfxMessageBox(str2);
}
子进程步骤2代码void CChildView::OnPipeWrite()
{
// TODO: Add your command handler code here
char buf[]="child write pipe";
DWORD dwWrite;
if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))
{
AfxMessageBox("管道写入失败!");
return;
}}
子进程步骤3代码void CChildView::OnPipeRead()
{
// TODO: Add your command handler code here
char buf[100];
DWORD dwRead;
if(!ReadFile(hRead,buf,100,&dwRead,NULL))
{
AfxMessageBox("读取管道失败!");
return;
}
AfxMessageBox(buf);
}
代码和书上的完全一样,没有哦发现有什么不同的地方
但是第一次创建管道的时候在建立子进程时,子进程无法获取父进程的读写管道的句柄,但是当我再次创建管道时,子进程能够读取父进程的低些句柄,但是读取到的却是第一次创建管道时父进程的读写句柄,即以后每次创建一个子进程,他获得的都是上一个父进程的读写句柄,而不是本次所重新创建的管道的读写句柄。
不知道这是为什么?书上的步骤是这样的:
对于父进程:
1、创建匿名管道
2、创建子进程
3、编写写入数据到管道的代码;
4、编写从管道读取数据的代码;对于子进程:
1、在建立窗口的时候获取父进程的读写句柄
2、编写相关到写入数据的代码;
3、编写从管道读取数据的代码;
对应的代码如下:父进程步骤1和2代码
void CParentView::OnPipeCreate()
{
// TODO: Add your command handler code here
SECURITY_ATTRIBUTES sa;
sa.bInheritHandle=true;
sa.lpSecurityDescriptor=NULL;
sa.nLength=sizeof(SECURITY_ATTRIBUTES); STARTUPINFO sui;
PROCESS_INFORMATION pi;
ZeroMemory(&sui,sizeof(STARTUPINFO));
sui.cb=sizeof(STARTUPINFO);
sui.dwFlags=STARTF_USESTDHANDLES;
sui.hStdInput=hRead;
sui.hStdOutput=hWrite;
sui.hStdError=GetStdHandle(STD_ERROR_HANDLE);
if(!CreatePipe(&hRead,&hWrite,&sa,0))
{
//CloseHandle(hRead);
//CloseHandle(hWrite);
AfxMessageBox("管道创建失败!");
return;
}
CString str1,str2;
str1.Format("hRead=%d",hRead);
str2.Format("hWrite=%d",hWrite);
AfxMessageBox(str1);
AfxMessageBox(str2); if(!CreateProcess("..\\Child\\Debug\\Child.exe",NULL,NULL,NULL,true,0,NULL,NULL,&sui,&pi))
{
CloseHandle(hRead);
CloseHandle(hWrite);
hRead=NULL;//防止在析构函数中再次调用CloseHandle
hWrite=NULL;
AfxMessageBox("进程创建失败!");
return;
}
else
{
CloseHandle(pi.hProcess);//在这里关闭
CloseHandle(pi.hThread);
}
}父进程步骤3代码
void CParentView::OnPipeWrite()
{
// TODO: Add your command handler code here
char buf[]="父类数据!";
DWORD dwWrite; if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))
{
AfxMessageBox("写入管道失败!");
return;
}
}
父进程步骤4代码
void CParentView::OnPipeRead()
{
// TODO: Add your command handler code here
char buf[100];
DWORD dwRead; if(!ReadFile(hRead,buf,100,&dwRead,NULL))
{
AfxMessageBox("读取管道失败!");
return;
} AfxMessageBox(buf);
}子进程代码:
子进程步骤1代码void CChildView::OnInitialUpdate()
{
CView::OnInitialUpdate();
// TODO: Add your specialized code here and/or call the base class
hRead=GetStdHandle(STD_INPUT_HANDLE);
hWrite=GetStdHandle(STD_OUTPUT_HANDLE); if(INVALID_HANDLE_VALUE ==hRead)
AfxMessageBox("hRead获取失败!");
if(INVALID_HANDLE_VALUE ==hWrite)
AfxMessageBox("hWrite获取失败!"); CString str1,str2;
str1.Format("child hRead=%d",hRead);
str2.Format("Child hWrite=%d",hWrite);
AfxMessageBox(str1);
AfxMessageBox(str2);
}
子进程步骤2代码void CChildView::OnPipeWrite()
{
// TODO: Add your command handler code here
char buf[]="child write pipe";
DWORD dwWrite;
if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))
{
AfxMessageBox("管道写入失败!");
return;
}}
子进程步骤3代码void CChildView::OnPipeRead()
{
// TODO: Add your command handler code here
char buf[100];
DWORD dwRead;
if(!ReadFile(hRead,buf,100,&dwRead,NULL))
{
AfxMessageBox("读取管道失败!");
return;
}
AfxMessageBox(buf);
}
解决方案 »
- 如何读取TXT一行数据?急急
- 恳求try()catch{}的用法
- 用VC 做过"<网页登陆>的朋友帮帮我,已经傻了CSDN的搜索是不是坏掉了.
- 计算机图形学的问题:看具体要求请进。(欢迎那些有时间想展示一下天赋的高手实践一下)
- hook shadow ssdt问题
- 在struct中定义的基础类型float的变量为什么无法通过编译???
- SP项目外包:有没有VC高手?winsocket和多线程和数据库比较熟悉的?
- udp数据序列出错如何解决
- 为什么我的程序由Shared Dll转成Static类型编译会出错?
- 怎么样得到鼠标的位置??
- error C2061: syntax error : identifier 'VERTEXARY'是什么原因
- winexec打开浏览器
sui.cb=sizeof(STARTUPINFO);
sui.dwFlags=STARTF_USESTDHANDLES;
sui.hStdInput=hRead;
sui.hStdOutput=hWrite;
sui.hStdError=GetStdHandle(STD_ERROR_HANDLE);