前段时间操作系统的实验课要求我们实现windows下进程间的通信,正好趁这个温习以下C#的写法,啊哈哈~····
目的
简单的说就是程序p1负责获取用户输入的要求,是打开程序并输入程序名或是关闭程序并输入程序名。然后p1将获取的数据通过进程间通信传给进程p2,p2负责程序的调度。
p1进程
p1要干的事情就是收集用户输入的信息,然后在发送给p2,这有点像web里面的客户端也就是前台哈。
1、收集前台信息包装 窗体设计如下,就不贴代码了,拖拖控件还是非常简单的
这里获取数据和asp.net一样,为了方便传输,将打开或关闭用数字表示,然后程序名string表示
1 2 int flag = (textBox1.Text.ToString().Equals("open" )) ? 1 : 0 ;String name = textBox2.Text.ToString();
进程间通信有三种方式,一种是共享内存,还有消息传输,还有剪贴板,这里面采用消息传输,也就是说用sendMessage这个函数,首先得调用动态链接库里的函数。
1 2 3 4 5 6 7 8 9 10 public struct My_lParam { public IntPtr dwData; public int cbData; [MarshalAs(UnmanagedType.LPStr)] public string lpData; } [DllImport("user32.dll" , EntryPoint = "SendMessage" )] private static extern int SendMessage (IntPtr wnd, int msg, int wP, ref My_lParam lP) ;
2、发送数据 然后就是传输数据,这里是通过button点击事件触发传送,如何找到p2进程则是通过获取当前所有进程的信息,然后一一排查它的名字然后找到p2
1 2 3 4 5 6 7 8 private void button1_Click (object sender, EventArgs e) { Process[] pros = Process.GetProcesses(); for (int i = 0 ; i < pros.Length; i++) { if (pros[i].ProcessName == "p2" ) } } }
3、p1完整代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public struct My_lParam { public IntPtr dwData; public int cbData; [MarshalAs(UnmanagedType.LPStr)] public string lpData; } [DllImport("user32.dll" , EntryPoint = "SendMessage" )] private static extern int SendMessage (IntPtr wnd, int msg, int wP, ref My_lParam lP) ;private void button1_Click (object sender, EventArgs e) { My_lParam lp = new My_lParam(); int flag = (textBox1.Text.ToString().Equals("open" )) ? 1 : 0 ; lp.dwData = (IntPtr)100 ; lp.lpData = textBox2.Text.ToString(); byte [] sarr = System.Text.Encoding.UTF8.GetBytes(lp.lpData); int len = sarr.Length; lp.cbData = len + 1 ; Process[] pros = Process.GetProcesses(); for (int i = 0 ; i < pros.Length; i++) { if (pros[i].ProcessName == "p2" ) IntPtr hWnd = pros[i].MainWindowHandle; SendMessage(hWnd, 0x4A , flag, ref lp); } } }
注意:
sendMessage的第二个参数必须得是0x4A,因为0x4A才表示向另一个进程传输数据
因为用了0x4A,所以sendMessage的第四个参数必须得是My_lParam这个结构体的样子
详细看官方文档
p2进程
p2进程就是接收来自p1发送的数据,然后根据发送的指令,如果收到第三个参数是1,则创建一个进程,否则结束该进程
p2界面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 public struct My_lParam { public IntPtr dwData; public int cbData; [MarshalAs(UnmanagedType.LPStr)] public string lpData; } protected override void DefWndProc (ref Message m) { base.DefWndProc(ref m); if (m.Msg == 0x4A ) { My_lParam mystr = new My_lParam(); Type mytype = mystr.GetType(); mystr = (My_lParam)m.GetLParam(mytype); string threadName = mystr.lpData; int flag = m.WParam.ToInt32(); if (flag == 1 ) { Process p = new Process(); p.StartInfo.FileName = System.IO.Path.Combine(Application.StartupPath, threadName + ".exe" ); p.StartInfo.Arguments = threadName + ".exe" ; p.StartInfo.UseShellExecute = true ; p.Start(); } else { Process[] p = Process.GetProcessesByName(threadName); for (int i = 0 ; i < p.Length; i++) { p[i].Kill(); p[i].Close(); } } } }
碎碎念
然后两个进程同时运行一下,就能实现进程间的通信了,而且还是实时的哦~ 代码写成这样基本就可以交差了,及格妥妥的!
The End~