C# 經過copydata實現進程間通訊

最近公司須要實現一個基於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

相關文章
相關標籤/搜索