您的位置:首页 > 编程语言 > C#

关于C#中实现两个应用程序消息通讯的问题

2012-11-28 21:19 453 查看
发送消息的函数:public static void SendMessage(string destProcessName, int msgID, string strMsg)

只能发送一个msgID和一个strMsg, 接收方只接收了strMsg,我的项目中已经够用了,你如果需要读msgID,还需要改一下。客户端代码请参考csdn上的原文自己写吧。


/*


进程之间通讯的几种方法:


在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯。常用的方法有


(1)使用内存映射文件


(2)通过共享内存DLL共享内存


(3)使用SendMessage向另一进程发送WM_COPYDATA消息





比起前两种的复杂实现来,WM_COPYDATA消息无疑是一种经济实惠的一种方法.


WM_COPYDATA消息的主要目的是允许在进程间传递只读数据。Windows在通过WM_COPYDATA消息传递期间,不提供继承同步方式。


SDK文档推荐用户使用SendMessage函数,接受方在数据拷贝完成前不返回,这样发送方就不可能删除和修改数据:





这个函数的原型及其要用到的结构如下:


SendMessage(hwnd, WM_COPYDATA, wParam, lParam);


其中:


WM_COPYDATA对应的十六进制数为0x004A


wParam设置为包含数据的窗口的句柄。


lParam指向一个COPYDATASTRUCT的结构:


typedef struct tagCOPYDATASTRUCT


{


DWORD dwData; //用户定义数据


DWORD cbData; //数据大小


PVOID lpData; //指向数据的指针


} COPYDATASTRUCT;


该结构用来定义用户数据。





具体过程如下:


首先,在发送方,用FindWindow找到接受方的句柄,然后向接受方发送WM_COPYDATA消息。


接受方在DefWndProc事件中处理这条消息。由于中文编码是两个字节, 所以传递中文时候字节长度要搞清楚。


protected override void DefWndProc(ref System.Windows.Forms.Message m) {


switch(m.Msg) {


case WinMessageUtil.WM_COPYDATA:


string str = WinMessageUtil.ReceiveMessage(ref m);


break;


default:


break;


}


base.DefWndProc(ref m);


}


*/




using System;


using System.Runtime.InteropServices;


using System.Diagnostics;




namespace Speeding.Util


{




//WM_COPYDATA消息所要求的数据结构


public struct CopyDataStruct


{


public IntPtr dwData;


public int cbData;




[MarshalAs(UnmanagedType.LPStr)]


public string lpData;


}





///


/// 本类封装了一些进程间通讯的细节


///


public class WinMessageUtil


{


public const int WM_COPYDATA = 0x004A;




//通过窗口的标题来查找窗口的句柄


[DllImport("User32.dll",EntryPoint="FindWindow")]


private static extern int FindWindow(string lpClassName, string lpWindowName);




//在DLL库中的发送消息函数


[DllImport("User32.dll",EntryPoint="SendMessage")]


private static extern int SendMessage


(


int hWnd, // 目标窗口的句柄


int Msg, // 在这里是WM_COPYDATA


int wParam, // 第一个消息参数


ref CopyDataStruct lParam // 第二个消息参数


);





///


/// 发送消息,只能传递一个自定义的消息ID和消息字符串,想传一个结构,但没成功


///


/// 目标进程名称,如果有多个,则给每个都发送


/// 自定义数据,可以通过这个来决定如何解析下面的strMsg


/// 传递的消息,是一个字符串


public static void SendMessage(string destProcessName, int msgID, string strMsg)


{


if(strMsg == null) return;




//按进程名称查找,同名称的进程可能有许多,所以返回的是一个数组


Process []foundProcess = Process.GetProcessesByName(destProcessName);


foreach(Process p in foundProcess)


{


int toWindowHandler = p.MainWindowHandle.ToInt32();


if(toWindowHandler != 0)


{


CopyDataStruct cds;


cds.dwData = (IntPtr) msgID; //这里可以传入一些自定义的数据,但只能是4字节整数


cds.lpData = strMsg; //消息字符串


cds.cbData = System.Text.Encoding.Default.GetBytes(strMsg).Length + 1; //注意,这里的长度是按字节来算的




//发送方的窗口的句柄, 由于本系统中的接收方不关心是该消息是从哪个窗口发出的,所以就直接填0了


int fromWindowHandler = 0;


SendMessage(toWindowHandler, WM_COPYDATA, fromWindowHandler, ref cds);


}


}


}




///


/// 接收消息,得到消息字符串


///


/// System.Windows.Forms.Message m


/// 接收到的消息字符串


public static string ReceiveMessage(ref System.Windows.Forms.Message m)


{


CopyDataStruct cds = (CopyDataStruct) m.GetLParam(typeof(CopyDataStruct));


return cds.lpData;


}




}







}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐