首页 > 系统相关 >c# 通过 SendMessage 实现跨进程数据通信

c# 通过 SendMessage 实现跨进程数据通信

时间:2024-05-26 18:55:00浏览次数:15  
标签:IntPtr 数据通信 c# System int SendMessage cds using public

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.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication9
{
    public partial class Form1 : Form
    {
        const string hwndMapName = "MyMediaPlayerServiceHwnd";
        const string messageResultMapName = "MyMediaPlayerServiceResult";
        const int resultBufferSize = 1 * 1024 * 1024;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // 创建或打开只读的内存映射文件
            MemoryMappedFile memoryMappedFile = MemoryMappedFile.CreateOrOpen(hwndMapName, sizeof(int));
            MemoryMappedViewAccessor accessor = memoryMappedFile.CreateViewAccessor();
            int sharedInt = this.Handle.ToInt32(); // 要写入的int值
            accessor.Write(0, ref sharedInt);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            new Form2().ShowDialog();
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct COPYDATASTRUCT
        {
            public IntPtr dwData; // 用于指定消息类型
            public int cbData; // 用于指定lpData指向的缓冲区的字节数
            public IntPtr lpData; // 用于指向要发送数据的指针
        }

        private const uint WM_COPYDATA = 0x004A;

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_COPYDATA)
            {
                var resultCode = 1;
                COPYDATASTRUCT cds = (COPYDATASTRUCT)Marshal.PtrToStructure(m.LParam, typeof(COPYDATASTRUCT));
                if (cds.cbData > 0 && cds.lpData != IntPtr.Zero)
                {
                    byte[] data = new byte[cds.cbData];
                    Marshal.Copy(cds.lpData, data, 0, cds.cbData);
                    string receivedString = System.Text.Encoding.Unicode.GetString(data);
                    using (MemoryMappedFile resultMappedFile = MemoryMappedFile.OpenExisting(messageResultMapName, MemoryMappedFileRights.ReadWrite))
                    {
                        // 从内存映射文件中读取int值
                        using (MemoryMappedViewAccessor resultAccessor = resultMappedFile.CreateViewAccessor())
                        {
                            var message = "Hi Sender!";
                            var result = Encoding.UTF8.GetBytes(message);
                            if (result.Length > resultBufferSize)
                                resultCode = 0;
                            else
                                resultAccessor.WriteArray(0, result, 0, result.Length);
                        }
                    }
                }

                m.Result = new IntPtr(resultCode);
                return;
            }

            base.WndProc(ref m);
        }
    }
}
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;
using System.IO.MemoryMappedFiles;

namespace WindowsFormsApplication9
{
    public partial class Form2 : Form
    {
        const string hwndMapName = "MyMediaPlayerServiceHwnd";
        const string messageResultMapName = "MyMediaPlayerServiceResult";
        const int resultBufferSize = 1 * 1024 * 1024;

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, ref COPYDATASTRUCT cds);

        private const uint WM_COPYDATA = 0x004A;

        [StructLayout(LayoutKind.Sequential)]
        private struct COPYDATASTRUCT
        {
            public IntPtr dwData;
            public int cbData;
            public IntPtr lpData;
        }

        public Form2()
        {
            InitializeComponent();
        }

        private void Form2_Load(object sender, EventArgs e)
        {
            textBox1.Text = SendMessage("Hi, Reciever!");
        }

        private string SendMessage(string message)
        {
            // 打开只读的内存映射文件,以读取目标窗口句柄
            using (MemoryMappedFile hwndMappedFile = MemoryMappedFile.OpenExisting(hwndMapName, MemoryMappedFileRights.ReadWrite))
            {
                // 从内存映射文件中读取int值
                using (MemoryMappedViewAccessor hwndAccessor = hwndMappedFile.CreateViewAccessor())
                {
                    int sharedInt;
                    hwndAccessor.Read(0, out sharedInt);

                    var hwnd = new IntPtr(sharedInt);

                    #region 向目标窗口发送消息

                    // 将字符串转换为字节数组
                    byte[] messageBytes = System.Text.Encoding.Unicode.GetBytes(message);

                    // 分配内存并将字节数组复制到内存中
                    IntPtr messagePtr = Marshal.AllocCoTaskMem(messageBytes.Length);
                    Marshal.Copy(messageBytes, 0, messagePtr, messageBytes.Length);

                    try
                    {
                        // 构造 COPYDATASTRUCT 结构体,将字符串指针和长度传递给接收方
                        COPYDATASTRUCT cds = new COPYDATASTRUCT();
                        cds.dwData = IntPtr.Zero;
                        cds.cbData = messageBytes.Length;
                        cds.lpData = messagePtr;

                        using (MemoryMappedFile resultMappedFile = MemoryMappedFile.CreateOrOpen(messageResultMapName, resultBufferSize, MemoryMappedFileAccess.ReadWrite))
                        {
                            // 使用 SendMessage 发送自定义消息
                            var result = SendMessage(hwnd, WM_COPYDATA, IntPtr.Zero, ref cds);
                            if (result.ToInt32() != 1)
                                return null;

                            // 创建一个内存映射视图
                            using (MemoryMappedViewAccessor accessor = resultMappedFile.CreateViewAccessor(0, resultBufferSize, MemoryMappedFileAccess.ReadWrite))
                            {
                                // 创建一个字节数组来接收读取的数据
                                byte[] byteArray = new byte[resultBufferSize];

                                // 从内存映射文件中读取字节数组
                                accessor.ReadArray(0, byteArray, 0, resultBufferSize);

                                // 将字节数组转换为字符串
                                string data = Encoding.UTF8.GetString(byteArray);
                                
                                // 去除末尾的 \0 字符
                                data = data.TrimEnd('\0');

                                return data;
                            }
                        }
                    }
                    finally
                    {
                        // 释放内存
                        Marshal.FreeCoTaskMem(messagePtr);
                    }

                    #endregion
                }
            }
        }
    }
}

 

标签:IntPtr,数据通信,c#,System,int,SendMessage,cds,using,public
From: https://www.cnblogs.com/nanfei/p/18214138

相关文章

  • FunClip - 阿里打造的创意魔剪:一键自动化短视频编辑,高效解锁视觉盛宴!
    ......
  • 2024年华为OD机试真题-计算面积-C++-OD统一考试(D卷)
     2024年OD统一考试(D卷)完整题库:华为OD机试2024年最新题库(Python、JAVA、C++合集)题目描述:绘图机器的绘图笔初始位置在原点(0,0),机器启动后其绘图笔按下面规则绘制直线:1)尝试沿着横向坐标轴正向绘制直线,直到给定的终点值E。2)期间可通过指令在纵坐标轴方向进行偏移,并同时绘制直......
  • (附nuclei yaml文件)H3C多款企业路由器actionpolicy_status信息泄露漏洞复现(管理员密码
    (附nucleiyaml文件)H3C多款企业路由器actionpolicy_status信息泄露漏洞复现(管理员密码泄露)声明本文仅用于技术交流,请勿用于非法用途由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。1、漏洞简介漏......
  • 地下城游戏(leetcode)
    个人主页:Lei宝啊 愿所有美好如期而遇地下城游戏https://leetcode.cn/problems/dungeon-game/description/图解+分析:代码classSolution{public:intcalculateMinimumHP(vector<vector<int>>&vv){introw=vv.size(),col=vv[0].size();......
  • 线程池(C++)
    个人主页:Lei宝啊 愿所有美好如期而遇线程池实现线程类#pragmaonce#include<pthread.h>#include<iostream>#include<vector>#include<string>#include<cstdlib>#include<cstring>#include<functional>#include<unistd.h>#in......
  • AtCoder Beginner Contest 355(F - MST Query)
    很久没有见到这么好的题了。原题面用ChatGPT......
  • 算法设计与分析 头哥educoder 批处理作业调度
     给定n个作业的集合{J1,J2,…,Jn}。每个作业必须先由机器1处理,然后由机器2处理。所有任务必须先由机器1处理完成后,才能由机器2处理,并且在机器2的处理顺序必须与机器1的处理顺序一致,处理顺序一旦确定不能改变。设作业Ji需要机器1的处理时间为Ai,需要机器2的处理时间为Bi,怎样安......
  • CV再放大招 | YOLOv10:毫秒级实时端到端目标检测开源模型
    〔探索AI的无限可能,微信关注“AIGCmagic”公众号,让智能科技点亮你的生活〕本文作者:AIGCmagic社区  猫先生5月25日凌晨,由清华多媒体智能组发布YOLOv10:毫秒级实时端到端目标检测开源模型。项目地址:https://github.com/THU-MIG/yolov10论文地址:https://arxiv.org/pdf/24......
  • 算法设计与分析 头哥educoder 旅行商问题
    设有n个城市组成的交通图,一个售货员从住地城市q出发,到其它城市各一次去推销货物,最后回到住地城市。要求:假定两个城市a,b从a到b的路程花费w_ab是已知的,问应该怎样选择一条花费最少的路线?输入格式:第一行nmq,n和m两个整数分别表示城市数n以及城市之间的单向路数量m,q表示住地城......
  • CSP历年复赛题-P1095 [NOIP2007 普及组] 守望者的逃离
    原题链接:https://www.luogu.com.cn/problem/P1095题意解读:在有限的时间内,通过跑步或者闪烁两种方式,能跑出的最远距离是多少,以及是否能跑出出口。解题思路:1、贪心法每一秒钟,都有两种选择:跑步(17米)、闪烁(60米,前提是蓝够10点,否则等待1s恢复4点蓝)经过计算,恢复足够的蓝到闪烁需要3.......