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;
        }
posted @   ꧁执笔小白꧂  阅读(515)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2020-12-26 C#-DataTable转化为自定义DataTable
2020-12-26 C#-读写Excel学习笔记
点击右上角即可分享
微信分享提示