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