c#利用VM_COPYDATA实现进程间通信
c#进程间的通信方式很多种,只会这种,感觉比较简单。不懂原理,能用就行。
假设有两个程序:server(主进程),client(子进程)
1.server端:
/*定义一个结构体,用来接收从子进程传过来的信息,与子进程定义的一样*/ public struct COPYDATASTRUCT { public IntPtr dwData; public int cbData; [MarshalAs(UnmanagedType.LPStr)] public string lpData; } /*定义一个消息类型,与子进程定义的一样*/ const int WM_COPYDATA = 0x004A; /*处理消息的方法*/ protected override void DefWndProc(ref System.Windows.Forms.Message m) { switch (m.Msg) { case WM_COPYDATA: COPYDATASTRUCT mystr = new COPYDATASTRUCT(); Type mytype = mystr.GetType(); mystr = (COPYDATASTRUCT)m.GetLParam(mytype); this.label2.Text = mystr.lpData; MessageBox.Show( mystr.lpData); break; default: base.DefWndProc(ref m); break; } }
2.client端:
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using System.Runtime.InteropServices; //引入这些命名空间 10 using System.Diagnostics; 11 12 namespace Client 13 { 14 public partial class Form1 : Form 15 { 16 public Form1() 17 { 18 InitializeComponent(); 19 } 20 21 /*发送消息的结构,与主进程一样*/ 22 public struct COPYDATASTRUCT 23 { 24 public IntPtr dwData; 25 public int cbData; 26 [MarshalAs(UnmanagedType.LPStr)] 27 public string lpData; 28 29 } 30 31 /*发送消息的类型,与主进程一样*/ 32 const int WM_COPYDATA = 0x004A; 33 34 /*通过这个方法,可以找到主进程的窗体*/ 35 [DllImport("User32.dll", EntryPoint = "FindWindow")] 36 private static extern int FindWindow(string lpClassName, string lpWindowName); 37 38 39 /*发送消息的结构体*/ 40 [DllImport("User32.dll", EntryPoint = "SendMessage")] 41 private static extern int SendMessage( 42 int hWnd, 43 int Msg, 44 int wParam, 45 ref COPYDATASTRUCT lParam 46 ); 47 48 49 private void button1_Click(object sender, EventArgs e) 50 { 51 /*C#进程通信(Server): 主进程的tilte*/ 52 int WINDOW_HANDLER = FindWindow(null, @"C#进程通信(Server)"); 53 if (WINDOW_HANDLER == 0) 54 { 55 } 56 else 57 { 58 int age = 12; 59 byte[] sarr = System.Text.Encoding.Default.GetBytes("hello,world"); 60 int len = sarr.Length; 61 COPYDATASTRUCT cds; 62 cds.dwData = (IntPtr)age; 63 cds.lpData = "hello,world"; 64 cds.cbData = len + 1; 65 SendMessage(WINDOW_HANDLER, WM_COPYDATA, 0, ref cds); 66 67 } 68 } 69 70 } 71 }
3.主要事项:
①.因为FindWindow这个方法是用来找到窗体的,所以server端一定要是winform程序,client可以是winform,也可以是控制台
②.当把发送消息的方法,放在循环中的时候,会降低程序的性能。上千或上万次的循环,效果会非常明显。
③.不需要引入其他的dll,直接原生态