A-A+
Winform跨进程通讯
有时候我们会遇到一些场景需要两个独立的应用程序能够交换数据信息,当然解决方案有很多种,比如使用TCP/IP、数据库等等,在这里我想介绍的是如何使用Windows API进行跨进程通讯。
最重要的Windows API函数为SendMessage,其原型及介绍如下:
- LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam);
hWnd:其窗口程序将接收消息的窗口的句柄。
Msg:指定被发送的消息。
wParam:指定附加的消息特定信息。
IParam:指定附加的消息特定信息。
返回值:返回值指定消息处理的结果,依赖于所发送的消息。
使用C#语言开发程序时,需要引用命名空间“System.Runtime.InteropServices”,然后再进行如下声明:
- [DllImport("User32.dll", EntryPoint = "SendMessage")]
- private static extern int SendMessage(
- IntPtr hWnd, //接收消息的主窗体句柄
- int Msg, // message
- int wParam, // first message parameter
- ref COPYDATASTRUCT lParam // second message parameter
- );
其中,COPYDATASTRUCT为一结构体,其声明如下:
- private struct COPYDATASTRUCT
- {
- public IntPtr dwData;
- public int cbData;
- [MarshalAs(UnmanagedType.LPStr)]
- public string lpData;
- }
假设现在有两个Winform应用程序,分别为A和B。在A中需要按照上文声明SendMessage及COPYDATASTRUCT,再声明常量WM_COPYDATA,如下所示:
- public const int WM_COPYDATA = 0x004A;
WM_COPYDATA将作为SendMessage中参数Msg的值进行传递。Msg的值为0X004A时代表该消息允许在进程间传递只读数据,此值如果被修改会发生错误,所以在不确定的情况下不要轻易更改。
在A中发送消息的函数如下:
- public static void SendMessage(IntPtr hWnd, string strMsg)
- {
- byte[] sarr = System.Text.Encoding.Default.GetBytes(strMsg);
- int len = sarr.Length + 1;
- COPYDATASTRUCT cds;
- cds.dwData = (IntPtr)100;
- cds.lpData = strMsg;
- cds.cbData = len;
- SendMessage(hWnd, WM_COPYDATA, 0, ref cds);
- }
在B中需要声明COPYDATASTRUCT及WM_COPYDATA,重写接收消息窗体的函数WndProc(ref Message m),如下所示:
- protected override void WndProc(ref Message m)
- {
- switch (m.Msg)
- {
- case WM_COPYDATA:
- COPYDATASTRUCT cds = new COPYDATASTRUCT();
- Type cdsType = cds.GetType();
- cds = (COPYDATASTRUCT)m.GetLParam(cdsType);
- this.textBox1.AppendText(cds.lpData + Environment.NewLine);
- break;
- default:
- base.WndProc(ref m);
- break;
- }
- }
最终的运行结果如下图所示:
示例程序下载:
参考资料: