进程之间通讯的几种方法:
在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯。常用的方法有
使用内存映射文件
通过共享内存DLL共享内存
使用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.textBox1 = new System.Windows.Forms.TextBox();
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(184, 24);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(128, 21);
this.textBox1.TabIndex = 0;
this.textBox1.Text = "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.textBox1});
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.GetBytes(this.textBox1.Text);
int len = sarr.Length;
COPYDATASTRUCT cds;
cds.dwData = (IntPtr) 100;
cds.lpData = this.textBox1.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.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(176, 32);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(160, 21);
this.textBox1.TabIndex = 0;
this.textBox1.Text = "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.textBox1});
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);
this.textBox1.Text =mystr.lpData;
break;
default:
base.DefWndProc(ref m);
break;
}
}
}
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)] public string lpData;
}
}
分享到:
相关推荐
通过这种方式,我们能够在C#中利用`SendMessage`函数实现简单的进程间通信。然而,这种方法并不适用于大规模的数据交换,因为其性能可能受到限制,且处理不当可能会导致程序错误。在更复杂的应用场景中,推荐使用更...
本实例聚焦于在C#中如何利用`SendMessage`函数进行进程间通信,这对于多任务环境下的软件开发至关重要。 `SendMessage`是Windows API中的一个函数,它允许一个窗口向另一个窗口发送消息,即使这两个窗口属于不同的...
C# Remoting是.NET Framework提供的一种跨进程通信技术,它允许不同进程间的对象互相调用方法,实现分布式系统中的组件交互。在这个场景中,我们关注的是如何利用C# Remoting来实现在不同进程之间传递消息并进行互...
在给定的"C#进程间通信.pdf"中,主要介绍了通过C#的`Process`类结合Win32 API函数来实现实时的数据传输。 首先,我们要理解进程间通信的基本概念。每个进程都有自己的独立内存空间,无法直接访问其他进程的内存。...
利用 `SendMessage` 和 `WM_COPYDATA` 实现进程间通信是一种简单而有效的方式,特别适合于小规模数据传输场景。通过本文介绍的方法,开发者可以轻松地在两个 EXE 之间建立通信通道,实现数据共享或交互功能。需要...
本实例将通过VS2008开发环境,详细介绍如何利用WM_消息来实现C#中的进程间通信。 WM_消息是Windows操作系统内核定义的一系列消息类型,它们在窗口之间传递信息。WM COPYDATA是WM_消息中的一种,专门用于进程间的...
进程间通信(IPC,Inter-Process Communication)是操作系统中一种重要的技术,允许不同进程之间交换数据和信息。在这个“VC+C# 实现的进程间通讯”项目中,开发者使用了两种常见的IPC方法:共享内存和消息传递。接...
本篇文章将详细探讨如何在QT框架下利用Windows窗口消息来实现进程间通信。 首先,让我们了解什么是QT。QT是一个跨平台的应用程序开发框架,由Qt Company提供,广泛用于创建GUI应用程序。它提供了丰富的API和工具,...
在VS2005环境下,我们可以利用WM_COPYDATA消息来实现C#进程间通信的一个简洁实例。 首先,我们需要了解WM_COPYDATA结构。这个结构包含了两个关键部分:dwData字段用于传递自定义整数值,而lpData字段则用于传递指向...
本篇文章将深入探讨如何在C#中利用`SendMessage`函数进行跨进程通信,以及与之相关的`WM_SETTEXT`和`WM_GETTEXT`消息。 首先,`SendMessage`是Windows API中一个基础的函数,用于在窗口间发送消息。其基本语法如下...
根据给定的信息,本文将详细解释如何利用C#语言调用Windows API来进行进程间通信,具体目标是自动填充网络认证所需的用户名、密码等信息。这一技术对于自动化日常操作、提高工作效率具有重要意义。 ### 设计背景 ...
- `CreatePipe`和`ReadFile`/`WriteFile`组合实现管道通信,允许数据在进程间传递。 - `CreateProcess`和`WaitForInputIdle`启动新的进程并等待其准备好接收消息。 - `WM_COPYDATA`消息通过`SendMessage`函数发送...
在C#编程中,进程间通信(Inter-Process Communication, IPC)是一项重要的技术,它允许不同的应用程序或进程之间交换数据和指令。标题“c# 进程之间发消息”涉及的就是如何在C#环境中实现在不同进程间发送消息。...
本示例主要探讨了如何实现C++程序与C#程序之间的通信,这通常涉及到不同进程间通信(IPC,Inter-Process Communication)的技术。在这个案例中,标签“管道”表明使用的是管道作为通信机制。下面我们将详细讲解这一...
"C# findwindow及sendmessage外挂"这个主题就是关于如何利用C#的FindWindow和SendMessage这两个API函数来实现程序间的通信,尤其是创建外挂程序。下面我们将深入探讨这两个函数以及它们在创建外挂中的应用。 ...
C# 通过`CopyData`实现进程间通信是一种在Windows平台上使用API函数进行跨进程数据交换的方法。在C#中,我们通常会借助P/Invoke技术来调用Windows API,以便利用非托管代码的能力。`CopyData`是Windows消息机制的一...
在本文中,我们将深入探讨如何使用C#编程语言结合Windows API来实现进程间通信(IPC),特别是通过发送和接收消息的方式。"C#利用API发送和接收消息Demo"项目展示了如何利用API函数实现在不同应用程序之间的消息传递...
在 C# 中,可以使用 WIN32 API 的 `SendMessage` 函数或 `PostMessage` 函数来实现进程间通信。 5. 内存管理:在使用 VirtualAllocEx 函数时,需要注意内存管理问题。需要确保在释放内存时,使用 `VirtualFreeEx` ...
通过学习这个API封装和示例代码,开发者可以快速掌握在C# WinForm应用中实现进程间通信的方法,提升应用程序的功能和扩展性。在实际项目中,可以根据需求选择适合的通信方式,确保进程间的协作高效、稳定。
在IT行业中,进程间通信(IPC,Inter-Process Communication)是一项关键的技术,它允许不同的应用程序或进程之间交换数据。在Windows Presentation Foundation(WPF)框架下,开发人员可以利用C#语言来实现这一功能...