关于C#中实现两个应用程序消息通讯的问题
最近項目中需要在兩個應用程序之間通訊,這里的兩個程序是在一臺機器上,看了csdn上的一篇文章《如何在C#用WM_COPYDATA消息來實現兩個進程之間傳遞數據》,原理是講清楚了,但使起來很不爽,決定自己封裝一下,滿足項目需要就行。
注意這里發送消息的函數:
只能發送一個msgID和一個strMsg,?接收方只接收了strMsg,我的項目中已經夠用了,你如果需要讀msgID,還需要改一下。客戶端代碼請參考csdn上的原文自己寫吧。
進程之間通訊的幾種方法:?
在Windows程序中,各個進程之間常常需要交換數據,進行數據通訊。常用的方法有??
?(1)使用內存映射文件??
?(2)通過共享內存DLL共享內存??
?(3)使用SendMessage向另一進程發送WM_COPYDATA消息??
?
比起前兩種的復雜實現來,WM_COPYDATA消息無疑是一種經濟實惠的一種方法.??
WM_COPYDATA消息的主要目的是允許在進程間傳遞只讀數據。Windows在通過WM_COPYDATA消息傳遞期間,不提供繼承同步方式。
?SDK文檔推薦用戶使用SendMessage函數,接受方在數據拷貝完成前不返回,這樣發送方就不可能刪除和修改數據:??
?
這個函數的原型及其要用到的結構如下:
其中:
?WM_COPYDATA對應的十六進制數為0x004A??
?wParam設置為包含數據的窗口的句柄。
?lParam指向一個COPYDATASTRUCT的結構:
該結構用來定義用戶數據。??
具體過程如下:?
首先,在發送方,用FindWindow找到接受方的句柄,然后向接受方發送WM_COPYDATA消息。
接受方在DefWndProc事件中處理這條消息。由于中文編碼是兩個字節,?所以傳遞中文時候字節長度要搞清楚。
接收方
?
protected override void DefWndProc(ref System.Windows.Forms.Message m) {switch (m.Msg){case WinMessageUtil.WM_COPYDATA:string str = WinMessageUtil.ReceiveMessage(ref m);break;default:break;}base.DefWndProc(ref m); }操作為
using System; using System.Runtime.InteropServices; using System.Diagnostics;namespace Speeding.Util {//WM_COPYDATA消息所要求的數據結構public struct CopyDataStruct{public IntPtr dwData;public int cbData;[MarshalAs(UnmanagedType.LPStr)]public string lpData;}/// <summary>/// 本類封裝了一些進程間通訊的細節/// </summary>public class WinMessageUtil{public const int WM_COPYDATA = 0x004A;//通過窗口的標題來查找窗口的句柄[DllImport("User32.dll", EntryPoint = "FindWindow")]private static extern int FindWindow(string lpClassName, string lpWindowName);//在DLL庫中的發送消息函數[DllImport("User32.dll", EntryPoint = "SendMessage")]private static extern int SendMessage(int hWnd, // 目標窗口的句柄 int Msg, // 在這里是WM_COPYDATAint wParam, // 第一個消息參數ref CopyDataStruct lParam // 第二個消息參數 );/// <summary>/// 發送消息,只能傳遞一個自定義的消息ID和消息字符串,想傳一個結構,但沒成功/// </summary>/// <param name="destProcessName">目標進程名稱,如果有多個,則給每個都發送</param>/// <param name="msgID">自定義數據,可以通過這個來決定如何解析下面的strMsg</param>/// <param name="strMsg">傳遞的消息,是一個字符串</param>public static void SendMessage(string destProcessName, int msgID, string strMsg){if (strMsg == null)return;//按進程名稱查找,同名稱的進程可能有許多,所以返回的是一個數組Process[] foundProcess = Process.GetProcessesByName(destProcessName);foreach (Process p in foundProcess){int toWindowHandler = p.MainWindowHandle.ToInt32();if (toWindowHandler != 0){CopyDataStruct cds;cds.dwData = (IntPtr) msgID; //這里可以傳入一些自定義的數據,但只能是4字節整數 cds.lpData = strMsg; //消息字符串cds.cbData = System.Text.Encoding.Default.GetBytes(strMsg).Length + 1; //注意,這里的長度是按字節來算的//發送方的窗口的句柄, 由于本系統中的接收方不關心是該消息是從哪個窗口發出的,所以就直接填0了int fromWindowHandler = 0;SendMessage(toWindowHandler, WM_COPYDATA, fromWindowHandler, ref cds);}}}/// <summary>/// 接收消息,得到消息字符串/// </summary>/// <param name="m">System.Windows.Forms.Message m</param>/// <returns>接收到的消息字符串</returns>public static string ReceiveMessage(ref System.Windows.Forms.Message m){CopyDataStruct cds = (CopyDataStruct) m.GetLParam(typeof(CopyDataStruct));return cds.lpData;}} }?
轉載于:https://www.cnblogs.com/DoNetCShap/archive/2012/06/26/2564460.html
總結
以上是生活随笔為你收集整理的关于C#中实现两个应用程序消息通讯的问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 页面上指定类型的控件的样式添加
- 下一篇: C# static readonly 与