最近公司需要實現一個基於copydata進程間通信的功能。原來一直沒有接觸過Windows的進程通信,這次正好可以學習一下。 程式是基於Winform的,下麵直接上代碼。 公共類: 發送方: 接收方: 註: 1、發送方和接收方均可以用C++、JAVA等實現,此處就不再做討論。 2、在發送方。如果接收 ...
最近公司需要實現一個基於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文檔。