你的位置:首页 > ASP.net教程

[ASP.net教程]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文档。