两个程序的进程间通信小结

时间:2020-12-22 14:01:43

进程间通信方法有很多,网上也有很多说明,如:发送消息,共享内存;命名管道、匿名管道,socket(这两个需要网卡的支持)。

A程序:mfc基于对话框程序

B程序:console程序

过程:当A处理完后得到十个数据(这个暂时通过txt文档存储,然后B程序读,这是待改进的地方,猜想:可以改为传递指针)。B程序处理完之后得到结果(简单的数),直接在A对话框中edit控件显示。

方法:1、发送消息(试过了几种方法,发现这种才是自己想要的)

A程序调用B程序:ShellExecute(NULL,"open","F:****.exe",NULL,NULL,SW_SHOWNORMAL); 

B程序结果完成后:

HWND hwnd=::FindWindow(NULL,"**");//寻找**窗口,并返回窗口句柄
if(hwnd!=NULL)
{
char text[3];
itoa(result,text,10);//将运行结果转换为字符串
HWND sta=::FindWindowEx(hwnd,NULL,"Edit",NULL);//找到**窗口中edit控件并返回其句柄
if(sta==NULL)
{
return;
}
::SendMessage(sta,WM_SETTEXT,0,(LPARAM)(LPCTSTR)text);//通过发送消息的方式,将结果作为参数传递给A程序并显示。
return;
}
else 
{
return;
}

注:要注意SendMessage和PostMessage两个函数的区别。前者等执行完返回,后者只是将消息放入消息队列就返回。一般采用前者。

2、共享内存(参考Visual C++开发技术大全中例子,以下尝试都是在两个基于对话框中的):

A程序:

       int sdata=199;

HANDLE hmap;
hmap=CreateFileMapping((HANDLE)0XFFFFFFFF,NULL,PAGE_READWRITE,0,0x100,"myshare");//创建虚拟内存空间的文件映射
if(hmap==NULL)
{
MessageBox("file mapping failed!");
CloseHandle(hmap);
hmap=NULL;
return FALSE;
}
LPSTR viewdata=(LPSTR)MapViewOfFile(hmap,FILE_MAP_ALL_ACCESS,0,0,0);//浏览映射
if(viewdata==NULL)
{
MessageBox("view mapping failed");
CloseHandle(hmap);
hmap=NULL;
return FALSE;
}
       itoa(sdata,viewdata,10);//veiwdata便是写进去的数据。
MessageBox(viewdata);
return TRUE;

B程序:

       HANDLE hmap=OpenFileMapping(FILE_MAP_READ,FALSE,"myshare");//打开已经建立的映射
if(hmap==NULL)
{
MessageBox("read failed");
CloseHandle(hmap);
hmap=NULL;
return;
}
LPSTR viewd=(LPSTR)MapViewOfFile(hmap,FILE_MAP_READ,0,0,0);//浏览映射
if(viewd==NULL)
{
MessageBox("veiw failed");
CloseHandle(hmap);
hmap=NULL;
return;
}
MessageBox(viewd);//viewd便是共享数据。
UnmapViewOfFile(viewd);

3、匿名管道(参考网上的程序):

HANDLE hRead,hWrite;
SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle=true;
sa.lpSecurityDescriptor=NULL;
if(!::CreatePipe(&hRead,&hWrite,&sa,0))//创建管道
{
AfxMessageBox("CreatePipe failed!");
return false;
}


STARTUPINFO si;
si.cb=sizeof(STARTUPINFO);
GetStartupInfo(&si); //该函数返回进程在启动时被指定的 STARTUPINFO 结构
si.dwFlags=STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;//决定本结构中每个成员是否起作用
si.wShowWindow=SW_HIDE;//这里设置是否显示DOS窗口
si.hStdError=hWrite;//标准错误模式
si.hStdOutput=hWrite;//标准输出
si.hStdInput=GetStdHandle(STD_INPUT_HANDLE);//标准输入
PROCESS_INFORMATION pi;
LPSTR lpszCmdLine="F:****.exe";//这里自己指定路径
if(!CreateProcess(NULL,lpszCmdLine,NULL,NULL,TRUE,0,NULL,0,&si,&pi))//创建进程
{
AfxMessageBox("CreateProcess failed!");
CloseHandle(hRead);
CloseHandle(hWrite);
return false;
}
CloseHandle(hWrite);
if(WaitForSingleObject(pi.hProcess,5000)==WAIT_TIMEOUT)//等待进程结束
{
AfxMessageBox("Timeout!");
TerminateThread(pi.hThread,1);
TerminateProcess(pi.hProcess,1);
CloseHandle(hRead);
return false;
}
char buf[4096]={0};
DWORD bytes;
if(::ReadFile(hRead,buf,4095,&bytes,NULL)==NULL)//读取程序输出
{
AfxMessageBox("ReadFile Failed!");
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(hRead);
return false;
}
else 
{
CString Result=buf;
MessageBox(Result);
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(hRead);
return true;

结果:读取了B程序在dos界面输出的所有数据,而我只是需要最后的结果,并不需要其中的中间变量数据。

待研究:将十个数据改为直接传入程序B(共享内存方式或许比较好)。