C# 通过copydata实现进程间通信

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# 通过copydata实现进程间通信相关的知识,希望对你有一定的参考价值。

最近公司需要实现一个基于copydata进程间通信的功能。原来一直没有接触过Windows的进程通信,这次正好可以学习一下。

程序是基于Winform的,下面直接上代码。

公共类:

public class ImportFromDLL
        {
            public const int WM_COPYDATA = 0x004A;

            //启用非托管代码  
            [StructLayout(LayoutKind.Sequential)]
            public struct COPYDATASTRUCT
            {
                public int dwData;    //not used  
                public int cbData;    //长度  
                [MarshalAs(UnmanagedType.LPStr)]
                public string lpData;
            }

            [DllImport("User32.dll")]
            public static extern int SendMessage(
                IntPtr hWnd,     // handle to destination window   
                int Msg,         // message  
                IntPtr wParam,    // first message parameter   
                ref COPYDATASTRUCT pcd // second message parameter   
            );

            [DllImport("User32.dll", EntryPoint = "FindWindow")]
            public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

            [DllImport("Kernel32.dll", EntryPoint = "GetConsoleWindow")]
            public static extern IntPtr GetConsoleWindow();

        }

 

发送方:

private void SendMessage()
        {
            //声明变量
            string filepath = @"D:\GetMsg.exe";//接收消息程序路径
            string strText= "hello world!";//发送的消息//遍历系统中运行的进程,获取接收消息的进程
            Process[] processes = Process.GetProcesses();
            Process process = null;
            foreach (Process p in processes)
            {
                try
                {
                    //这两个进程的某些属性一旦访问就抛出没有权限的异常
                    if (p.ProcessName != "System" && p.ProcessName != "Idle")
                    {
                        if (p.ProcessName == "GetMsg")
                        {
                            process = p;
                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }

            //如果接收消息的进程未运行,则开启程序
            if (process == null)
            {//启动接收消息程序
                process = System.Diagnostics.Process.Start(filepath);                
                Thread.Sleep(100);//等待接收消息的程序完全打开,否则消息不能发送成功。
            }

            //接收端的窗口句柄  
            IntPtr hwndRecvWindow = process.MainWindowHandle;

            //自己的进程句柄
            IntPtr hwndSendWindow = Process.GetCurrentProcess().Handle;
            
            //填充COPYDATA结构
            ImportFromDLL.COPYDATASTRUCT copydata = new ImportFromDLL.COPYDATASTRUCT();
            copydata.cbData = Encoding.Default.GetBytes(strText).Length; //长度 注意不要用strText.Length;  
            copydata.lpData = strText;//内容  

            //发送消息
            ImportFromDLL.SendMessage(hwndRecvWindow, ImportFromDLL.WM_COPYDATA, hwndSendWindow, ref copydata);

            return;
        }

 接收方:

protected override void WndProc(ref Message m)
        {
            if (m.Msg == ImportFromDLL.WM_COPYDATA)//根据Message.Msg区分消息类型,ImportFromDLL.WM_COPYDATA为发送方定义的消息类型
            {
                ImportFromDLL.COPYDATASTRUCT copyData = (ImportFromDLL.COPYDATASTRUCT)m.GetLParam(typeof(ImportFromDLL.COPYDATASTRUCT));//获取数据
                MessageBox.Show(copyData.lpData);
            }
            base.WndProc(ref m);
        }

注:

1、发送方和接收方均可以用C++、JAVA等实现,此处就不再做讨论。

2、在发送方。如果接收方未开启,就打开接收方,在打开的同时,使用了:

Thread.Sleep(100);//等待接收消息的程序打开,否则消息不能发送成功

让程序等待。若不想让程序等待,由想传递消息给接收方,则可以考虑使用一下开启进程的重载方法:

public static Process Start(string fileName, string arguments);
public static Process Start(string fileName, string userName, SecureString password, string domain);
public static Process Start(string fileName, string arguments, string userName, SecureString password, string domain);

具体使用说明,可参照API文档。

 

以上是关于C# 通过copydata实现进程间通信的主要内容,如果未能解决你的问题,请参考以下文章

利用WM_COPYDATA消息实现进程间通信

进程间通信之WM_COPYDATA

C# 进程间通信之二传递复杂数据类型(转)

IPC进程间通信之四数据复制消息WM_COPYDATA

c#进程之间对象传递方法

从 C++ 到 C# 的 WM_COPYDATA