c#进程间同步实现进程之间通讯的⼏种⽅法
进程之间通讯的⼏种⽅法:
常⽤的⽅法有:
1.使⽤内存映射⽂件
2.通过共享内存DLL共享内存
3.使⽤SendMessage向另⼀进程发送WM_COPYDATA消息.
⽐起前两种的复杂实现来,WM_COPYDATA消息⽆疑是⼀种经济实惠的⼀中⽅法.(ZT)
WM_COPYDATA消息的主要⽬的是允许在进程间传递只读数据。Windows在通过WM_COPYDATA消息传递期间,不提供继承同步⽅式。SDK⽂档推荐⽤户使⽤SendMessage函数,接受⽅在数据拷贝完成前不返回,这样发送⽅就不可能删除和修改数据:
这个函数的原型及其要⽤到的结构如下:
SendMessage(hwnd,WM_COPYDATA,wParam,lParam);
其中,WM_COPYDATA对应的⼗六进制数为0x004A
wParam设置为包含数据的窗⼝的句柄。lParam指向⼀个COPYDATASTRUCT的结构:
typedef struct tagCOPYDATASTRUCT{
DWORD dwData;//⽤户定义数据
DWORD cbData;//数据⼤⼩
PVOID lpData;//指向数据的指针
}COPYDATASTRUCT;
该结构⽤来定义⽤户数据。
具体过程如下:
⾸先,在发送⽅,⽤FindWindow到接受⽅的句柄,然后向接受⽅发送WM_COPYDATA消息.
接受⽅在DefWndProc事件中,来处理这条消息.由于中⽂编码是两个字节,所以传递中⽂时候字节长度要搞清楚.体代码如下:
//---------------------------------------------------
//发送⽅:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
namespace WinFormSendMsg
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Button button1;
private System.ComponentModel.Container components = null;
const int WM_COPYDATA = 0x004A;
public Form1()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// textBox1
//
/
/
// button1
//
this.button1.Location = new System.Drawing.Point(344, 16); this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(112, 32);
this.button1.TabIndex = 1;
this.button1.Text = "button1";
this.button1.Click += new System.EventHandler(this.button1_Click); //
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14); this.ClientSize = new System.Drawing.Size(536, 142);
this.Controls.AddRange(new System.Windows.Forms.Control[] { this.button1,
this.Name = "Form1";
this.Text = "发送⽅窗体";
this.ResumeLayout(false);
}
static void Main()
{
Application.Run(new Form1());
}
[DllImport("User32.dll",EntryPoint="SendMessage")]
private static extern int SendMessage(
int hWnd, // handle to destination window
int Msg, // message
int wParam, // first message parameter
ref COPYDATASTRUCT lParam // second message parameter );
[DllImport("User32.dll",EntryPoint="FindWindow")]
private static extern int FindWindow(string lpClassName,string lpWindowName);
private void button1_Click(object sender, System.EventArgs e)
{
int WINDOW_HANDLER = FindWindow(null,@"接收⽅窗体");
if(WINDOW_HANDLER == 0)
{
}
else
{
byte[] sarr = System.Text.Encoding.Default.Box1.Text); int len = sarr.Length;
COPYDATASTRUCT cds;
cds.dwData = (IntPtr) 100;
cds.lpData = Box1.Text;
cds.cbData = len + 1;
SendMessage(WINDOW_HANDLER, WM_COPYDATA, 0, ref cds);
}
}
}
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)] public string lpData;
}
}
//---------------------------------------------------
//接受⽅
/
/---------------------------------------------------
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
namespace WindowsFormGetMsg
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.TextBox textBox1;
private System.ComponentModel.Container components = null;
const int WM_COPYDATA = 0x004A;
public Form1()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
}
base.Dispose( disposing );
}
private void InitializeComponent()
{
this.SuspendLayout();
//
// textBox1
//
//
/
/ Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(432, 266);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.Name = "Form1";
this.Text = "接收⽅窗体";
this.ResumeLayout(false);
}
static void Main()
{
进程通信方式Application.Run(new Form1());
}
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);
break;
default:
base.DefWndProc(ref m);
break;
}
}
}
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)] public string lpData;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论