C#-exe间通讯(一)-发送消息SendMessage
一、SendMessage帮助类:
/**
*┌──────────────────────────────────────────────────────────────┐
*│ 描 述:两个exe程序之间通信_发送消息传递(SendMessageAPI)
*│ 作 者:执笔小白
*│ 版 本:1.0
*│ 创建时间:2022-12-06 10:40:56
*└──────────────────────────────────────────────────────────────┘
*┌──────────────────────────────────────────────────────────────┐
*│ 命名空间: Communication_Between_exe_ProgramsHelper
*│ 类 名:Communication_SendMessageAPIHelper
*└──────────────────────────────────────────────────────────────┘
*/
using System.Runtime.InteropServices;
namespace Communication_Between_exe_ProgramsHelper
{
/// <summary>
/// 两个exe程序之间通信_发送消息传递(SendMessageAPI)
/// </summary>
public static class Communication_SendMessageAPIHelper
{
/// <summary>
/// 当一个应用程序传递数据给另一个应用程序时发送此消息
/// </summary>
public static readonly int WM_COPYDATA = 0x004A;
#region 发送消息
/// <summary>
/// 查找窗口句柄
/// </summary>
/// <param name="lpClassName">类名</param>
/// <param name="lpWindowName">窗口标题</param>
/// <returns></returns>
[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">附加消息,根据msg参数区分使用</param>
/// <param name="lParam">发送数据</param>
/// <returns></returns>
[DllImport("User32.dll", EntryPoint = "SendMessage")]
public static extern int SendMessage(int hWnd, int msg, int wParam, ref COPYDATASTRUCT lParam);
/// <summary>
/// 发送消息的示例
/// </summary>
//private static void SendMsgDemo()
//{
// // 根据标题查找到句柄
// int hWnd = FindWindow(null, "接收消息的窗口的窗口名");
// // 数据
// string Msgstr = "数据";
// COPYDATASTRUCT cds;
// cds.dwData = 0;
// cds.cbData = System.Text.Encoding.Default.GetBytes(Msgstr).Length + 1;
// cds.lpData = Msgstr;
// // 发送
// SendMessage(hWnd, WM_COPYDATA, 0, ref cds);
//}
#endregion 发送消息
#region 接收消息
/// <summary>
/// 接收消息示例_WinForm(重写DefWndProc函数或者WndProc函数)
/// </summary>
//protected override void WndProc(ref Message m)
//{
// if (m.Msg == WM_COPYDATA)
// {
// COPYDATASTRUCT myStr = (COPYDATASTRUCT)m.GetLParam(typeof(COPYDATASTRUCT));
// string MsgStr = myStr.lpData;
// rTxtSendMsg_msg.AppendText(MsgStr);
// }
// base.WndProc(ref m);
//}
// WPF
//StringBuilder stringBuilder = new(); // 历史记录
//protected override void OnSourceInitialized(EventArgs e)
//{
// base.OnSourceInitialized(e);
// HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
// if (source != null)
// {
// IntPtr windowHandle = source.Handle;
// source.AddHook(HwndHandler); // 添加方法
// }
//}
///// <summary>
///// 钩子执行的方法
///// </summary>
//private IntPtr HwndHandler(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
//{
// if (msg == Communication_SendMessageAPIHelper.WM_COPYDATA)
// {
// COPYDATASTRUCT myStr = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam, typeof(COPYDATASTRUCT));
// stringBuilder.Append(myStr.lpData + ",");
// txtSendMessage_Msg.Text = stringBuilder.ToString();
// }
// handled = false;
// return IntPtr.Zero;
//}
#endregion 接收消息
}
/// <summary>
/// 消息数据载体
/// </summary>
public struct COPYDATASTRUCT
{
public IntPtr dwData; // 若发送较小数据可用此字段传输
public int cbData; // 发送数据的大小(以字节为单位)
[MarshalAs(UnmanagedType.LPStr)]
public string lpData; // 发送数据
}
}
二、发送端:
/// <summary>
/// 发送消息传递_发送
/// </summary>
private void BtnSedMsg_Click(object sender, EventArgs e)
{
// 根据标题查找到句柄
int hWnd = Communication_SendMessageAPIHelper.FindWindow(null, "接收端");
// 数据
string Msgstr = txtSedMsg_msg.Text.Trim();
COPYDATASTRUCT cds;
cds.dwData = (IntPtr)0;
cds.cbData = System.Text.Encoding.Default.GetBytes(Msgstr).Length + 1;
cds.lpData = Msgstr;
// 发送
_ = Communication_SendMessageAPIHelper.SendMessage(hWnd, Communication_SendMessageAPIHelper.WM_COPYDATA, 0, ref cds);
}
三、接收端:
1、WinForm:
/// <summary>
/// 发送消息方式-接收
/// </summary>
/// <param name="m"></param>
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_COPYDATA)
{
COPYDATASTRUCT myStr = (COPYDATASTRUCT)m.GetLParam(typeof(COPYDATASTRUCT));
string MsgStr = myStr.lpData;
rTxtSendMsg_msg.AppendText(MsgStr);
}
base.WndProc(ref m);
}
2、WPF:
// 记录
StringBuilder stringBuilder = new();
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
if (source != null)
{
IntPtr windowHandle = source.Handle;
source.AddHook(HwndHandler); // 添加方法
}
}
/// <summary>
/// 钩子执行的方法
/// </summary>
private IntPtr HwndHandler(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == Communication_SendMessageAPIHelper.WM_COPYDATA)
{
COPYDATASTRUCT myStr = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam, typeof(COPYDATASTRUCT));
stringBuilder.Append(myStr.lpData+",");
txtSendMessage_Msg.Text = stringBuilder.ToString();
}
handled = false;
return IntPtr.Zero;
}
本文来自博客园,作者:꧁执笔小白꧂,转载请注明原文链接:https://www.cnblogs.com/qq2806933146xiaobai/p/17005042.html
分类:
C#
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2020-12-26 C#-DataTable转化为自定义DataTable
2020-12-26 C#-读写Excel学习笔记