使用WM_COPYDATA实现跨进程通讯(下)

请注意:
A、SendMessage在接收方处理完毕前不会返回,会产生严重阻塞
B、由于使用了非托管内存,要注意进行清理

1、发送方WinForm

        public const int WM_COPYDATA = 0x004A;
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
        public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        private struct COPYDATASTRUCT
        {
            public IntPtr dwData;
            public int cbData;
            public IntPtr lpData;
        }

        public void sendData(String msg, Boolean isUnicode)
        {
            COPYDATASTRUCT cds = new COPYDATASTRUCT();
            cds.cbData = (msg.Length + 1) * (isUnicode ? 2:1);
            cds.lpData = (isUnicode ? Marshal.StringToCoTaskMemUni(msg) : Marshal.StringToCoTaskMemAnsi(msg));

            IntPtr cdsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(cds));
            Marshal.StructureToPtr(cds, cdsPtr, false);

            IntPtr clientWnd = Win32Helper.GetCurrentWindowHandle();
            SendMessage(clientWnd, WM_COPYDATA, IntPtr.Zero, cdsPtr);

            Marshal.FreeHGlobal(cdsPtr);
            Marshal.FreeCoTaskMem(cds.lpData);
        }

2、接收方WinForm

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        private struct COPYDATASTRUCT
        {
            public IntPtr dwData;
            public int cbData;
            public string lpData;
        }

        public const int WM_COPYDATA = 0x004A;
        protected override void WndProc(ref System.Windows.Forms.Message msg)
        {
            string msgTxt = "";
            COPYDATASTRUCT cds = new COPYDATASTRUCT();
            switch (msg.Msg)
            {
                case WM_COPYDATA:
                    if(msg.LParam!=IntPtr.Zero)
                    {
                        cds = (COPYDATASTRUCT)msg.GetLParam(cds.GetType());
                        String msgstr = cds.lpData;
                        //MessageBox.Show(msgstr);
                    }
                    break;
                default:
                    base.WndProc(ref msg);
                    break;
            }
        }

Comments are closed.