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,直接原生态

posted @ 2013-09-05 13:05  楪夕  阅读(801)  评论(2编辑  收藏  举报