最近项目中需要在两个应用程序之间通讯,这里的两个程序是在一台机器上,看了csdn上的一篇文章《如何在C#用WM_COPYDATA消息来实现两个进程之间传递数据》,原理是讲清楚了,但使起来很不爽,决定自己封装一下,满足项目需要就行。

注意这里发送消息的函数:

public static void SendMessage(string destProcessName, int msgID, string strMsg);

只能发送一个msgID和一个strMsg, 接收方只接收了strMsg,我的项目中已经够用了,你如果需要读msgID,还需要改一下。客户端代码请参考csdn上的原文自己写吧。

进程之间通讯的几种方法:

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

(1)使用内存映射文件  
 (2)通过共享内存DLL共享内存  
 (3)使用SendMessage向另一进程发送WM_COPYDATA消息  
 
比起前两种的复杂实现来,WM_COPYDATA消息无疑是一种经济实惠的一种方法.  
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事件中处理这条消息。由于中文编码是两个字节, 所以传递中文时候字节长度要搞清楚。

接收方

protected override void DefWndProc(ref  System.Windows.Forms.Message m)
{switch (m.Msg){case WinMessageUtil.WM_COPYDATA:string str = WinMessageUtil.ReceiveMessage(ref m);break;default:break;}base.DefWndProc(ref  m);
}

操作为

using System;
using System.Runtime.InteropServices;
using System.Diagnostics;namespace Speeding.Util
{//WM_COPYDATA消息所要求的数据结构public struct CopyDataStruct{public IntPtr dwData;public int cbData;[MarshalAs(UnmanagedType.LPStr)]public string lpData;}/// <summary>/// 本类封装了一些进程间通讯的细节/// </summary>public class WinMessageUtil{public const int WM_COPYDATA = 0x004A;//通过窗口的标题来查找窗口的句柄[DllImport("User32.dll", EntryPoint = "FindWindow")]private static extern int FindWindow(string lpClassName, string lpWindowName);//在DLL库中的发送消息函数[DllImport("User32.dll", EntryPoint = "SendMessage")]private static extern int SendMessage(int hWnd,                        // 目标窗口的句柄  int Msg,                        // 在这里是WM_COPYDATAint wParam,                    // 第一个消息参数ref  CopyDataStruct lParam        // 第二个消息参数
            );/// <summary>/// 发送消息,只能传递一个自定义的消息ID和消息字符串,想传一个结构,但没成功/// </summary>/// <param name="destProcessName">目标进程名称,如果有多个,则给每个都发送</param>/// <param name="msgID">自定义数据,可以通过这个来决定如何解析下面的strMsg</param>/// <param name="strMsg">传递的消息,是一个字符串</param>public static void SendMessage(string destProcessName, int msgID, string strMsg){if (strMsg == null)return;//按进程名称查找,同名称的进程可能有许多,所以返回的是一个数组Process[] foundProcess = Process.GetProcessesByName(destProcessName);foreach (Process p in foundProcess){int toWindowHandler = p.MainWindowHandle.ToInt32();if (toWindowHandler != 0){CopyDataStruct cds;cds.dwData = (IntPtr) msgID;   //这里可以传入一些自定义的数据,但只能是4字节整数      cds.lpData = strMsg;            //消息字符串cds.cbData = System.Text.Encoding.Default.GetBytes(strMsg).Length + 1;  //注意,这里的长度是按字节来算的//发送方的窗口的句柄, 由于本系统中的接收方不关心是该消息是从哪个窗口发出的,所以就直接填0了int fromWindowHandler = 0;SendMessage(toWindowHandler, WM_COPYDATA, fromWindowHandler, ref  cds);}}}/// <summary>/// 接收消息,得到消息字符串/// </summary>/// <param name="m">System.Windows.Forms.Message m</param>/// <returns>接收到的消息字符串</returns>public static string ReceiveMessage(ref  System.Windows.Forms.Message m){CopyDataStruct cds = (CopyDataStruct) m.GetLParam(typeof(CopyDataStruct));return cds.lpData;}}
}

转载于:https://www.cnblogs.com/DoNetCShap/archive/2012/06/26/2564460.html

关于C#中实现两个应用程序消息通讯的问题相关推荐

  1. Java黑皮书课后题第7章:*7.28(数学:组合)编写一个程序,提示用户输入10个整数,然后显示从这10个数中选出两个数的所有组合

    7.28(数学:组合) 题目 题目描述 破题 代码 运行示例 题目 题目描述 *7.28(数学:组合)编写一个程序,提示用户输入10个整数,然后显示从这10个数中选出两个数的所有组合 破题 声明一个长 ...

  2. Java黑皮书课后题第5章:*5.43(数学:组合)编写程序,显示从整数1到7中选择两个数字的所有组合,同时显示所有组合的总个数

    5.43(数学:组合)编写程序,显示从整数1到7中选择两个数字的所有组合,同时显示所有组合的总个数 题目 题目概述 破题 运行示例(要求) 代码 题目 题目概述 5.43(数学:组合)编写程序,显示从 ...

  3. 用户输入一个列表和两个整数作为下标,然后使用切片获取并输出列表中结余两个下标之间的元素组成的子列表。例如,用户输入 [1,2,3,4,5,6]和2,5,程序输出[3,4,5]。

    用户输入一个列表和两个整数作为下标,然后使用切片获取并输出列表中结余两个下标之间的元素组成的子列表.例如,用户输入 [1,2,3,4,5,6]和2,5,程序输出[3,4,5]. a = list(in ...

  4. 1.简述一个Activity跳转到另一个Activity时,两个Activity生命周期方法的执行过程。2.编写一个程序,要求在第一个界面中输入两个数字,在第二个界面显示第一个界面两个数字的和。

    1.简述一个Activity跳转到另一个Activity时,两个Activity生命周期方法的执行过程. 首先,我创建了一个MainActivity和SecondActivity两个Activity. ...

  5. matlab绘制两个函数,用matlab程序 在同一图中绘制两个函数,这两个函数分别是: , ,,matlab怎样同时画出两个函数图...

    导航:网站首页 > 用matlab程序 在同一图中绘制两个函数,这两个函数分别是: , ,,matlab怎样同时画出两个函数图 用matlab程序 在同一图中绘制两个函数,这两个函数分别是: , ...

  6. 利用多态特性,编程创建一个手机类Phones,定义打电话方法call()。创建两个子类:苹果手机类IPhone和安卓手机类APhone,并在各自类中重写方法call(),编写程序入口main()方法

    利用多态特性,编程创建一个手机类Phones,定义打电话方法call().创建两个子类:苹果手机类IPhone和安卓手机类APhone,并在各自类中重写方法call(),编写程序入口main()方法, ...

  7. uniapp 微信小程序 最近写的两个小程序中都会有,微信分享的设置,每次都在单个页面中写相同的内容,修改很不友好。下面全局分享代码做了记录

    最近写的两个小程序中都会有,微信分享的设置,每次都在单个页面中写相同的内容,修改很不友好.下面全局分享代码做了割记录 首先在小程序中配置微信分享,和微信朋友圈, onShareAppMessage, ...

  8. 在Linux环境下用C语言编写一个乘法程序mult,从命令行接收两个数字,然后输出其乘积;再用C语言编写一个exec1程序,在程序中使用execvp调用mult程序计算5与10的乘积。

    在Linux环境下用C语言编写一个乘法程序mult,从命令行接收两个数字,然后输出其乘积:再用C语言编写一个exec1程序,在程序中使用execvp调用mult程序计算5与10的乘积. 1.mult. ...

  9. 小程序中实现两个或者多个小程序之间互相跳转

    前言: 小程序中实现两个或者多个小程序之间互相跳转,a小程序带参跳转到b小程序中. 官方入口:wx.navigateToMiniProgram(Object object) 点我https://dev ...

最新文章

  1. python线程池及其原理和使用
  2. centos apt-get java_CentOS安装jdk的三种方法
  3. Python之NumPy(axis=0 与axis=1)区分
  4. Java Bootstrap:Dropwizard与Spring Boot
  5. 【ubuntu】ubuntu14.04上安装搜狗输入法
  6. SVN 清理失败解决方案
  7. 安川机器人报错代码_今日 IPO|对标库卡机器人的先惠技术上市 近八成收入靠上汽...
  8. 导航无限级菜单 java,Element NavMenu 无限级菜单
  9. server2003 IIS 错误 解决
  10. 软件工程——认识方法、模型、工具和技术
  11. C#.NET学习笔记11,12---布尔表达式2组合,if语句
  12. C#存取数据为所欲为(二)
  13. 如何在 Swift 中进行错误处理
  14. 双十一值得入手的数码好物有哪些?分享几款不错的数码好物
  15. java vnc server_VNCServer 配置 及Vncview的使用
  16. 2019年最新版,百度云不限速下载工具,亲测好用!
  17. MSDC 4.3 接口规范(26)
  18. 学习matlab体会,matlab学习心得体会
  19. html调用一言api,纯 JavaScript 实现网站一言功能
  20. 浙江大学计算机科学排名,2017浙江大学专业排名结果

热门文章

  1. 分布式数据库管理系统介绍
  2. 项目测试基础:白盒测试相关知识笔记
  3. 为啥你用@JsonFormat注解反序列化LocalDateTime总失败?
  4. 数据库:30种SQL语句优化,进阶必备!
  5. 收集100条实用的网络知识
  6. mysql强制禁止使用索引_MYSQL强制使用索引和禁止使用索引
  7. 阿拉伯语排版设计_针对说阿拉伯语的用户的测试和设计
  8. figma设计_5位来自杂乱无章的设计师的Figma技巧
  9. ux和ui_设计更好的结帐体验-UX / UI案例研究
  10. 小屏幕 ui设计_UI设计基础:屏幕