首页 > 代码库 > C# 通过copydata实现进程间通信

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

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

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

公共类:

public class ImportFromDLL        {            public const int WM_COPYDATA = http://www.mamicode.com/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 = http://www.mamicode.com/new ImportFromDLL.COPYDATASTRUCT();            copydata.cbData = Encoding.Default.GetBytes(strText).Length; //长度 注意不要用strText.Length;              copydata.lpData = http://www.mamicode.com/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实现进程间通信