首页 > 系统相关 >C#:进程之间传递数据

C#:进程之间传递数据

时间:2022-09-04 08:22:06浏览次数:86  
标签:C# WM System 进程 int COPYDATA 传递数据 using public

  • 一、思路

    Windows程序中,各个进程之间常常需要交换数据,进行数据通讯。常用的方法有

    • 使用内存映射文件
    • 通过共享内存DLL共享内存
    • 使用SendMessage向另一进程发送WM_COPYDATA消息

    比起前两种的复杂实现来,WM_COPYDATA消息无疑是一种经济实惠的一中方法。WM_COPYDATA消息的主要目的是允许在进程间传递只读数据。Windows在通过WM_COPYDATA消息传递期间,不提供继承同步方式。SDK文档推荐用户使用SendMessage函数,接受方在数据拷贝完成前不返回,这样发送方就不可能删除和修改数据:

    这个函数的原型及其要用到的结构如下:

    SendMessage(hwnd,WM_COPYDATA,wParam,lParam);
    

    其中,WM_COPYDATA对应的十六进制数为0x004AwParam设置为包含数据的窗口的句柄。lParam指向一个COPYDATASTRUCT的结构:

    typedef struct tagCOPYDATASTRUCT
    {
    	DWORD dwData;//用户定义数据
    	DWORD cbData;//数据大小
    	PVOID lpData;//指向数据的指针
    } COPYDATASTRUCT;
    

    该结构用来定义用户数据。

    二、具体过程

    在发送方,用FindWindow找到接受方的句柄,然后向接受方发送WM_COPYDATA消息。

    在接受方,在DefWndProc事件中来处理这条消息。由于中文编码是两个字节,所以传递中文时候字节长度要搞清楚。

    发送方代码:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    namespace Client
    {
    	public partial class FrmClient : Form
    	{
    		public FrmClient()
    		{
    			InitializeComponent();
    		}
    		private void FrmClient_Load(object sender, EventArgs e)
    		{
    		}
    
    		[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);
    
    		public struct COPYDATASTRUCT
    		{
    			public IntPtr dwData;
    			public int cbData;
    			[MarshalAs(UnmanagedType.LPStr)]
    			public string lpData;
    		}
    		const int WM_COPYDATA = 0x004A;
    
    		private void btnSend_Click(object sender, EventArgs e)
    		{
    			int WINDOW_HANDLER = FindWindow(null, @"C#进程间通信(Server)");
    			if (WINDOW_HANDLER != 0)
    			{
    				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);
    			}
    		}
    	}
    }
    

    接收端代码:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    namespace Server
    {
    	public partial class FrmServer : Form
    	{
    		public FrmServer()
    		{
    			InitializeComponent();
    		}
    		private void Form1_Load(object sender, EventArgs e)
    		{
    		}
    
    		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);
    				lblMsg.Text = "收到消息:" + mystr.lpData;
    				MessageBox.Show ("收到消息:" + mystr.lpData);
    				break;
    			default:
    				base.DefWndProc(ref m);
    				break;
    			}
    		}
    	}
    }
    

    三、相关资料

标签:C#,WM,System,进程,int,COPYDATA,传递数据,using,public
From: https://www.cnblogs.com/zhaoshujie/p/16654206.html

相关文章

  • MySQL教程 - 存储过程与自定义函数(Produce & Function)
    更新记录转载请注明出处。2022年9月4日发布。2022年9月4日从笔记迁移到博客。存储过程与函数说明存储过程和函数是一条或多条SQL语句的集合存储过程的返回值通......
  • CSP-S模拟1 [斐波那契,数颜色,分组]
    CSP-S模拟1洛谷上原题,不挂题面了。A.斐波那契P3938斐波那契观察上图,可发现规律:一个数的父亲等于这个数减去最大的小于它的斐波那契数。特殊的,如果这个数是斐波那契......
  • [Google] LeetCode 329 Longest Increasing Path in a Matrix 记忆化搜索
    Givenanmxnintegersmatrix,returnthelengthofthelongestincreasingpathinmatrix.Fromeachcell,youcaneithermoveinfourdirections:left,right......
  • 【WPF】wpf怎么绑定多个值,多个控件 绑定多个CommandParameter 命令参数
    最近有不少wpf新手问wpf的命令怎么绑定多个控件,很多人为此绞尽脑汁,网上的答案找了也没找到靠谱的,其实用MultiBinding就可以了。从.net3.0版本开始,就支持MultiBinding关于......
  • Source Map
    1.什么是SourceMapSourceMap就是一个信息文件,里面储存着位置信息。也就是说SourceMap文件中存储着压缩混淆后的代码,所对应的转换前的位置。有了它,出错的时候,除错......
  • NC19885 [AHOI2009]CHESS 中国象棋
    题目链接题目题目描述在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮。请问有多少种放置方法,中国像棋中炮的行走方式大家应该很清楚吧.一个......
  • 15.web开发-SpringMVC自动配置概览
    SpringBootprovidesauto-configurationforSpringMVCthatworkswellwithmostapplications.(大多场景我们都无需自定义配置)Theauto-configurationaddsthef......
  • C语言字符串处理函数 puts()和fputs()的区别及使用
    ​字符串函数(Stringprocessingfunction)也叫字符串处理函数,指的是编程语言中用来进行字符串处理的函数。本文主要介绍C语言中符串处理函数puts()和fputs()的区别使用方......
  • Centos7 常用优化脚本
    #!/bin/bash#服务器一键优化工具functiondefine_check_network(){echo主机名为`hostname-f`pingwww.baidu.com-c6}functiondefine_yum(){#......
  • codeforces#818(Div.2)
    算了,不摆烂了,事情太多,没摆烂的时间了。在我研究出如何把某平台上多年积累的流量变现前,就继续用这个博客记录日常吧。之后所有内容基于时间,就懒得设置标签分类之类的了。昨......