WM_COPYDATA实现的不同进程间通信
一、找到新软件需被通知的窗口(一般是以配置的形式实现)
二、发送消息
三、将对象序列化为字符串及反序列化的操作,通过一个帮助类实现
Demo代码:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
namespace Dralee.AppTransferMsg.Common
{
[Serializable]
public class Msg
{
public string SentBy { get; set; }
public string RcvBy { get; set; }
public string Message { get; set; }
public DateTime SentOn { get; set; }
public Msg()
{
}
public Msg(string sentBy, string rcvBy, string msg, DateTime sentOn)
{
SentBy = sentBy;
RcvBy = rcvBy;
Message = msg;
SentOn = sentOn;
}
public static byte[] Serialize(Msg msg)
{
MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, msg);
byte[] buffer = ms.GetBuffer();
ms.Close();
return buffer;
//return Encoding.Unicode.GetString(buffer);
}
public static Msg Deserialize(byte[] buffer)
{
MemoryStream ms = new MemoryStream(buffer);
BinaryFormatter bf = new BinaryFormatter();
Msg msg = (Msg)bf.Deserialize(ms);
return msg;
}
}
/// <summary>
/// 传输结构
/// </summary>
public struct CopyDataStruct
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}
}
转换帮助类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Dralee.AppTransferMsg.Common
{
// CreatedBy: Jackie Lee
// CreatedOn: 2016-08-17
/// <summary>
/// 字节数组与字符串互转
/// </summary>
public class HexConverter
{
/// <summary>
/// 字节数组转
/// </summary>
/// <param name="buffer"></param>
/// <returns></returns>
public string ByteToString(byte[] buffer)
{
StringBuilder sb = new StringBuilder();
for(int i = ; i < buffer.Length; ++i)
{
sb.AppendFormat("{0:X2}", buffer[i]);
}
return sb.ToString();
}
/// <summary>
/// 字符串转字节数组
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public byte[] StringToByte(string str)
{
if(string.IsNullOrEmpty(str) || str.Length % != )
{
return null;
}
byte[] buffer = new byte[str.Length / ];
string hex;
int j = ;
for(int i = ; i < buffer.Length;++i)
{
hex = new string(new char[] { str[j], str[j + ]});
buffer[i] = HexToByte(hex);
j += ;
}
return buffer;
}
/// <summary>
/// 双字节字符转byte
/// </summary>
/// <param name="hex"></param>
/// <returns></returns>
public byte HexToByte(string hex)
{
if (hex.Length > )
return ;
char[] hexs = hex.ToArray();
if(hexs.Length == )
{
return (byte)NumByChar(hexs[]);
}
else
{
return (byte)(NumByChar(hexs[]) * + NumByChar(hexs[]));
}
}
private byte NumByChar(char ch)
{
switch(ch)
{
case '': return ;
case '': return ;
case '': return ;
case '': return ;
case '': return ;
case '': return ;
case '': return ;
case '': return ;
case '': return ;
case '': return ;
case 'A': return ;
case 'B': return ;
case 'C': return ;
case 'D': return ;
case 'E': return ;
case 'F': return ;
default:
return ;
}
}
}
}
API类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Dralee.AppTransferMsg.Common
{
public static class API
{
public const int WM_COPYDATA = 0x004A;
[DllImport("User32.dll", EntryPoint = "FindWindow")]
public static extern int FindWindow(string lpClassName, string lpWindowName);
/// <summary>
/// 发送消息
/// </summary>
/// <param name="hwnd">目标句柄</param>
/// <param name="msg"></param>
/// <param name="wParam">参数1</param>
/// <param name="lParam">参数2</param>
/// <returns></returns>
[DllImport("User32.dll", EntryPoint = "SendMessage")]
public static extern int SendMessage(int hwnd, int msg, int wParam, ref CopyDataStruct lParam);
}
}
发送端:
private void btnSend_Click(object sender, EventArgs e)
{
Msg msg = new Msg { SentBy = txtSentBy.Text.Trim(), RcvBy = txtRcvBy.Text.Trim(), Message = txtMsg.Text.Trim(), SentOn = DateTime.Parse(txtSentOn.Text) };
//long size = GC.GetTotalMemory(true);
int hwnd = API.FindWindow(null, "(测试)->接收者");
if (hwnd == )
return;
string msgStr = new HexConverter().ByteToString(Msg.Serialize(msg));
CopyDataStruct cds;
cds.dwData = (IntPtr);
cds.cbData = (int)msgStr.Length + ;
cds.lpData = msgStr; API.SendMessage(hwnd, API.WM_COPYDATA, ,ref cds);
}
接收端,通过重写以实现对消息监控:
protected override void DefWndProc(ref Message m)
{
switch(m.Msg)
{
case API.WM_COPYDATA:
CopyDataStruct cds = (CopyDataStruct)m.GetLParam(typeof(CopyDataStruct));
//Msg msg = (Msg)m.GetLParam(typeof(Msg));
byte[] buffer = new HexConverter().StringToByte(cds.lpData);
Msg msg = Msg.Deserialize(buffer);
txtMsg.Text = msg.Message;
txtRcvBy.Text = msg.RcvBy;
txtSentBy.Text = msg.SentBy;
txtSentOn.Text = msg.SentOn.ToLongDateString();
break;
default:
base.DefWndProc(ref m);
break;
}
}
效果:

WM_COPYDATA实现的不同进程间通信的更多相关文章
- WM_COPYDATA+BHO+Qt实现进程间通信
最近项目有一个需求:点击网页上某个按钮,通知Qt客户端.网页相关操作使用了BHO,BHO与Qt通信通过WB_COPYDATA,为什么这么麻烦呢,因为项目正好用到了BHO,可能还有其他方式,能直接通过网 ...
- WM_COPYDATA进程间通信方案
连续在两个公司使用WM_COPYDATA实现进程间通信了,整理一下 具体步骤: 一. 进程A通过ShellExecute启动进程B, 将用于通信的窗口句柄hWndA(已强转为int值)通过命令行参 ...
- 【IPC进程间通信之四】数据复制消息WM_COPYDATA
IPC进程间通信+数据复制消息WM_COPYDATA IPC(Inter-Process Communication,进程间通信). 数据复制消息WM_C ...
- 利用WM_COPYDATA消息实现进程间通信
进程间通信最简单的方式就是发送WM_COPYDATA消息,下面通过例子来实现. 发送WM_COPYDATA消息: SendMessage(hRecvWnd, WM_COPYDATA, (WPARAM) ...
- 进程间通信之WM_COPYDATA方式反思,回顾和总结
许多Windows程序开发者喜欢使用WM_COPYDATA来实现一些进程间的简单通信(笔者也正在学习共享内存的一些知识来实现一些更高级的通信),这篇文章描述了笔者在使用这项技术时候的一些总结以及所遇到 ...
- 进程间通信的WM_COPYDATA的使用
http://blog.csdn.net/ao929929fei/article/details/6316174 接收数据的一方 ON_WM_COPYDATA() afx_msg BOOL OnCop ...
- 利用WM_COPYDATA进行进程间通信
发信消息 void CControlDlg::OnBnClickedButtonSend() { // TODO: 在此添加控件通知处理程序代码 CString strWindowTitle = _T ...
- CE 进程间通信
WINCE下进程间通信常用的方式有:剪贴板(Clipboard),网络套接字(Socket),WM_COPYDATA消息,共享内存,管道(消息队列),注册表等 剪贴板 //////////////// ...
- [转]Windows进程间通信的各种方法
http://www.cnblogs.com/songQQ/archive/2009/06/03/1495764.html 道相似,不过它传输数据是通过不可靠的数据报(如TCP/IP协议中的UDP包) ...
随机推荐
- MyBatis Cache配置
@(MyBatis)[Cache] MyBatis Cache配置 MyBatis提供了一级缓存和二级缓存 配置 全局配置 配置 说明 默认值 可选值 cacheEnabled 全局缓存的开关 tru ...
- 测试数组push和unshift方法的效率
先贴代码,之后再来补内容 <!DOCTYPE HTML> <html> <head> <title>测试数组push和unshift方法的效率</ ...
- Css3阴影实例
阴影大约从CSS2就开始有了,但是只有Safari一个浏览器支持它,到现在依然是这样.阴影在CSS3中可以应用在边框和文字上,就像图片的阴影效果一样.一般可以分为: box-shadow textsh ...
- python和数据科学(Anaconda)
Python拥有着极其丰富且稳定的数据科学工具环境.遗憾的是,对不了解的人来说这个环境犹如丛林一般(cue snake joke).在这篇文章中,我会一步一步指导你怎么进入这个PyData丛林. 你可 ...
- word2vec参数调整 及lda调参
一.word2vec调参 ./word2vec -train resultbig.txt -output vectors.bin -cbow 0 -size 200 -window 5 -neg ...
- MyEclipse安装插件的几种方法
本文讲解MyEclipse(MyEclipse10)的三种方法,以SVN为例 Eclipse update site URL: http://subclipse.tigris.org/update_1 ...
- 【Java】正则表达式
正则表达式是做什么的? 正则表达式可用在处理字符串,满足查找符合某些复杂规则的字符串的需要.简言之,正则表达式是记录文本规则的代码. 上图~
- 一个java源文件中为什么只能有一个public类。
我们都遇到过一个源文件中有多个java类,但当第一个类使用public修饰时,如果下面还有类使用public修饰,会报错.也就是是说一个java源文件最多只能有一个public类. 当有一个publi ...
- 一些js
//fixed块随滚动条滚动 window.onscroll=function(){ var scroll_left = $(window).scrollLeft(); $('#table_fixed ...
- Maven的POM.xml配置大全
<?xml version="1.0" encoding="utf-8"?> <project xmlns="http://mave ...