最近公司須要實現一個基於copydata進程間通訊的功能。原來一直沒有接觸過Windows的進程通訊,此次正好能夠學習一下。dom
程序是基於Winform的,下面直接上代碼。ide
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); }
一、發送方和接收方都可以用C++、JAVA等實現,此處就再也不作討論。學習
二、在發送方。判斷到接收方還沒有開啓,就執行打開接收方程序的代碼,在打開的同時,使用了線程等待:spa
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文檔。code