C#发送消息实现进程间通讯
最近在研究c#的进程之间通信,主要有四种方法:管道,Socket,共享内存,和今天要介绍的消息通信。虽然这种方式不一定是最优的,不过同步的通信方式提供了更多的稳定性,唯一性。而且逻辑简单不难理解,就是通过搜索另一个进程当前的窗口名称,然后拿到其句柄,就可以调用c++的类进行消息通信。本篇的写法就是将Wndproc的第四个参数改写成一个自我定义的数据结构,这样就可以传输整型以外的数据了(大部分情况下都是会以字符串做信息载体)。
发送端代码
private void update_Load(object sender, EventArgs e)
{
//第一个参数为接收端的窗口名称,对应的是winform中外观里的Text属性,第二个参数为信息
ProcessDialogue.Send("接收端", "Hello");
}
接收端代码
private const int WM_COPYDATA = 0x004A;
//此函数为窗口过程的回调函数(WndProc),在发送端声明同样的函数结构,即可实现互相通信
protected override void WndProc(ref System.Windows.Forms.Message e)
{
//标识判断
if (e.Msg == WM_COPYDATA)
{
ProcessDialogue.CopyDataStruct cds = (ProcessDialogue.CopyDataStruct)e.GetLParam(typeof(ProcessDialogue.CopyDataStruct));
//MessageBox.Show(cds.lpData);
//获得反馈后,发送相关消息
ProcessDialogue.Send("发送端", Constant.domain + "已经收到消息:" + cds.lpData);
}
base.WndProc(ref e);
}
公共代码(发送端和接收端都要有)
class ProcessDialogue
{
//第一重载
public static void Send(IntPtr hWnd, string text)
{
CopyDataStruct cds;
cds.dwData = (IntPtr)1; //这里可以传入一些自定义的数据,但只能是4字节整数
cds.lpData = text; //消息字符串
cds.cbData = System.Text.Encoding.Default.GetBytes(text).Length + 1;
//注意,这里的长度是按字节来算的
//int ptr = FindWindow(null, "Form1");
int ptr = hWnd.ToInt32();
SendMessage(ptr, WM_COPYDATA, 0, ref cds);
// 这里要修改成接收窗口的标题“接收端”
}
//第二重载
public static void Send(string hWnd, string text)
{
CopyDataStruct cds;
cds.dwData = (IntPtr)1; //这里可以传入一些自定义的数据,但只能是4字节整数
cds.lpData = text; //消息字符串
cds.cbData = System.Text.Encoding.Default.GetBytes(text).Length + 1;
//注意,这里的长度是按字节来算的
int ptr = FindWindow(null, hWnd);
//int ptr = hWnd.ToInt32();
SendMessage(ptr, WM_COPYDATA, 0, ref cds);
// 这里要修改成接收窗口的标题“接收端”
}
//窗口过程的回调函数所使用的标识
public const int WM_COPYDATA = 0x004A;
//用于存储数据的结构
public struct CopyDataStruct
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}
//通过窗口的标题来查找窗口的句柄
[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 // 第二个消息参数
);
}