Windows平台下使用Sendmessage方法实现Unity不同进程间通信的技巧

在Windows平台上。使用Sendmessage方法实现Unity不同进程之间通信。

核心代码

using System;

using System.Collections;

using System.Collections.Generic;

using System.Runtime.InteropServices;

using System.Text;

using UnityEngine;

/// <summary>

/// 传递的数据结构

/// </summary>

public struct COPYDATASTRUCT

{

    public IntPtr dwData;

    public int cData;

    [MarshalAs(UnmanagedType.LPStr)]

    public string lpData;

}

/// <summary>

/// 收到消息的数据结构,里面包含COPYDATASTRUCT数据

/// </summary>

public struct CWPRETSTRUCT

{

    public IntPtr lparam;//指定的消息内容

    public IntPtr wparam;//消息内容

    public uint message;//消息类型

    public IntPtr hwnd;//发送消息的句柄

}

public class WindowsProcessCommunication

{

    //全局监听

    private const int WH_CALLWNDPROC = 4;

    private const int WM_COPYDATA = 0x004A;

    [DllImport("User32.dll")]

    public static extern IntPtr SendMessage(IntPtr hwnd, int msg, IntPtr wParam, ref COPYDATASTRUCT IParam);

    [DllImport("User32.dll")]

    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    //设置一个监听

    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

    private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, uint dwThreadId);

    //移除对应事件的监听

    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

    private static extern bool UnhookWindowsHookEx(int idHook);

    // 传递当前事件给下一个处理器

    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

    private static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);

    //委托

    private delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);

    public delegate void ReciveMsgCallback(string msg);

    private static ReciveMsgCallback reciveMsgCallback;

    static int hookID = 0;

    

    private static IntPtr myWindows;

    /// <summary>

    /// 目标窗体的进程名称

    /// </summary>

    /// <param name="msgContent"></param>

    /// <param name="targetWindow"></param>

    public static void SendMessage(string msgContent, IntPtr targetWindow)

    {

        myWindows = FindWindow(null, Application.productName);

        String strSent = msgContent;

        if (targetWindow != IntPtr.Zero)

        {

            byte[] arr = System.Text.Encoding.Default.GetBytes(strSent);

            int len = arr.Length;

            COPYDATASTRUCT cdata;

            cdata.dwData = (IntPtr)100;

            cdata.lpData = strSent;

            cdata.cData = len + 1;

            SendMessage(targetWindow, WM_COPYDATA, myWindows, ref cdata);

            //Debug.LogError(msgContent);

        }

    }

    public static void HookLoad(ReciveMsgCallback rmsg)

    {

        reciveMsgCallback = rmsg;

        Debug.LogError("绑定回调");

        HookProc lpfn = new HookProc(Hook);

        IntPtr hInstance = IntPtr.Zero;

        hookID = SetWindowsHookEx(WH_CALLWNDPROC, lpfn, hInstance, (uint)AppDomain.GetCurrentThreadId());

        if (hookID<0) { 

            UnhookWindowsHookEx(hookID);

        }

        

    }

    //卸载钩子

    public static void UnhookWindowsHookEx()

    {

        if (hookID>0)

        {

            UnhookWindowsHookEx(hookID);

        }

    }

    private static unsafe int Hook(int nCode, IntPtr wParam, IntPtr lParam)

    {

        try

        {

            CWPRETSTRUCT m = (CWPRETSTRUCT)Marshal.PtrToStructure(lParam, typeof(CWPRETSTRUCT));

            if (m.message == WM_COPYDATA)

            {

                COPYDATASTRUCT cdata = (COPYDATASTRUCT)Marshal.PtrToStructure(m.lparam, typeof(COPYDATASTRUCT));

                reciveMsgCallback?.Invoke(cdata.lpData);

            }

            return CallNextHookEx(hookID, nCode, wParam, lParam);

        }

        catch (Exception ex)

        {

            Debug.LogError(ex.Message);

            return 0;

        }

    }

}

调用代码

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.UI;

public class NewBehaviourScript : MonoBehaviour

{

    public InputField receviceInputField;

    public InputField msgInputField;

    public Text receiveMsgText;

    public Button sendMsg;

    private void Start()

    {

        sendMsg.onClick.AddListener(() =>

        {

            if (!string.IsNullOrEmpty(msgInputField.text)) {

               

                WindowsProcessCommunication.SendMessage(msgInputField.text, WindowsProcessCommunication.FindWindow(null, receviceInputField.text));

            }

        });

        WindowsProcessCommunication.HookLoad(ReciveMsgCallback);

    }

    public void ReciveMsgCallback(string msg) {

        Debug.LogError("收到消息:" + msg);

        receiveMsgText.text ="收到消息:"+ msg;

    }

    private void OnDestroy()

    {

        WindowsProcessCommunication.UnhookWindowsHookEx();

    }

}

工程地址:https://github.com/994935108/WindowsProcessCommunication.git

QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空